Comment puis-je Subdiviser des lignes dans une base de données en R sur la base d'un vecteur de valeurs?

j'ai deux ensembles de données qui sont censés être de la même taille mais ne le sont pas. Je dois réduire les valeurs de A qui ne sont pas dans B et vice versa afin d'éliminer le bruit d'un graphique qui va dans un rapport. (Ne vous inquiétez pas, ces données ne sont pas effacées de façon permanente!)

j'ai lu ce qui suit:

Voici mon code:

bg2011missingFromBeg <- setdiff(x=eg2011$ID, y=bg2011$ID)
#attempt 1
eg2011cleaned <- subset(eg2011, ID != bg2011missingFromBeg)
#attempt 2
eg2011cleaned <- eg2011[!eg2011$ID %in% bg2011missingFromBeg]

le premier essai élimine simplement la première valeur dans le vecteur setdiff résultant. Le second essai donne des résultats et une erreur lourde:

Error in `[.data.frame`(eg2012, !eg2012$ID %in% bg2012missingFromBeg) 
:  undefined columns selected
36
demandé sur Community 2013-03-05 19:37:42

4 réponses

cela vous donnera ce que vous voulez:

eg2011cleaned <- eg2011[!eg2011$ID %in% bg2011missingFromBeg, ]

L'erreur dans votre deuxième tentative est parce que vous avez oublié le ,

en général, pour des raisons de commodité, la spécification object[index] sous-groupe les colonnes pour une 2d object . Si vous voulez sous-traiter les lignes et garder toutes les colonnes, vous devez utiliser la spécification object[index_rows, index_columns] , alors que index_cols peut être laissé en blanc, qui utilisera toutes les colonnes par défaut.

Cependant, vous devez toujours inclure le , pour indiquer que vous voulez pour obtenir un sous-ensemble de lignes au lieu d'un sous-ensemble de colonnes.

55
répondu adibender 2017-06-06 09:32:23

si vous voulez vraiment sous-traiter chaque base de données par un indice qui existe dans les deux bases de données, vous pouvez le faire avec la fonction 'match', comme ceci:

data_A[match(data_B$index, data_A$index, nomatch=0),]
data_B[match(data_A$index, data_B$index, nomatch=0),]

c'est, cependant, le même que:

data_A[data_A$index %in% data_B$index,]
data_B[data_B$index %in% data_A$index,]

Voici une démo:

# Set seed for reproducibility.
set.seed(1)

# Create two sample data sets.
data_A <- data.frame(index=sample(1:200, 90, rep=FALSE), value=runif(90))
data_B <- data.frame(index=sample(1:200, 120, rep=FALSE), value=runif(120))

# Subset data of each data frame by the index in the other.
t_A <- data_A[match(data_B$index, data_A$index, nomatch=0),]
t_B <- data_B[match(data_A$index, data_B$index, nomatch=0),]

# Make sure they match.
data.frame(t_A[order(t_A$index),], t_B[order(t_B$index),])[1:20,]

#    index     value index.1    value.1
# 27     3 0.7155661       3 0.65887761
# 10    12 0.6049333      12 0.14362694
# 88    14 0.7410786      14 0.42021589
# 56    15 0.4525708      15 0.78101754
# 38    18 0.2075451      18 0.70277874
# 24    23 0.4314737      23 0.78218212
# 34    32 0.1734423      32 0.85508236
# 22    38 0.7317925      38 0.56426384
# 84    39 0.3913593      39 0.09485786
# 5     40 0.7789147      40 0.31248966
# 74    43 0.7799849      43 0.10910096
# 71    45 0.2847905      45 0.26787813
# 57    46 0.1751268      46 0.17719454
# 25    48 0.1482116      48 0.99607737
# 81    53 0.6304141      53 0.26721208
# 60    58 0.8645449      58 0.96920881
# 30    59 0.6401010      59 0.67371223
# 75    61 0.8806190      61 0.69882454
# 63    64 0.3287773      64 0.36918946
# 19    70 0.9240745      70 0.11350771
15
répondu Dinre 2013-03-05 15:48:52

Really human comprehensive exemple (comme c'est la première fois que j'utilise %en%), Comment comparer deux bases de données et garder seulement des lignes contenant les valeurs égales dans la colonne spécifique:

# Set seed for reproducibility.
set.seed(1)

# Create two sample data frames.
data_A <- data.frame(id=c(1,2,3), value=c(1,2,3))
data_B <- data.frame(id=c(1,2,3,4), value=c(5,6,7,8))

# compare data frames by specific columns and keep only 
# the rows with equal values 
data_A[data_A$id %in% data_B$id,]   # will keep data in data_A
data_B[data_B$id %in% data_A$id,]   # will keep data in data_b

Résultats:

> data_A[data_A$id %in% data_B$id,]
  id value
1  1     1
2  2     2
3  3     3

> data_B[data_B$id %in% data_A$id,]
  id value
1  1     5
2  2     6
3  3     7
2
répondu maycca 2016-04-13 20:56:31

selon les commentaires sur le post original, les fusions / jointures sont bien adaptés à ce problème. En particulier, une "inner join ne retournera que les valeurs qui sont présentes dans les deux images de données, ce qui rend la déclaration setdiff inutile.

en utilisant les données de L'exemple de Dinre:

en base R:

cleanedA <- merge(data_A, data_B[, "index"], by = 1, sort = FALSE)
cleanedB <- merge(data_B, data_A[, "index"], by = 1, sort = FALSE)

utilisant le paquet dplyr:

library(dplyr)
cleanedA <- inner_join(data_A, data_B %>% select(index))
cleanedB <- inner_join(data_B, data_A %>% select(index))

pour conserver les données sous la forme de deux tableaux distincts, chacun ne contenant que ses propres variables, ce sous-ensemble de la table non désirée à sa seule variable d'index avant de rejoindre. Alors aucune nouvelle variable n'est ajoutée au tableau résultant.

1
répondu Sam Firke 2015-04-02 13:40:57