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:
- sélection de colonnes dans la base de données R basée sur celles *non * dans un vecteur
- http://www.ats.ucla.edu/stat/r/faq/subset_R.htm
- comment combiner plusieurs conditions pour sous-traiter une base de données en utilisant "ou"?
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
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.
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
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
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.