J'essaie d'utiliser une fonction de base simple pour mapper des valeurs si les deux valeurs correspondent à deux blocs de données, alors l'ancienne valeur doit rester
a1 b1 1 sale bb2 2 sale2 cc2 3 sale3 d2
Résultat souhaité:
XXX
3 Réponses :
En supposant que vous entendiez faire correspondre les valeurs par position, voici une solution de base R. Cela peut être plus facile avec des paquets tels que data.table ou dplyr, mais en général bien sûr, c'est bien d'avoir une idée de l'utilisation de la base R.
Il y a certainement de meilleures façons d'obtenir le résultat ci-dessous. Je n'utilise généralement pas la base R pour ce type de jointures
# date frames from above without factors!! df2$new <- ifelse(df2$b1 == df1$a1, df1$b1, df2$b1) df2 #> sale b1 new #> 1 sale b2 bb2 #> 2 sale2 c2 cc2 #> 3 sale3 d2 d2
Remarque J'ai changé le nom dans les blocs de données et changé les facteurs en caractères, ce qui rend la fusion possible.
La clé est de créer une variable qui permet la fusion / jointure (comment vous voulez l'appeler). J'utilise vente - cela permet de faire correspondre par position.
Merci @WaltS d'avoir indiqué une option beaucoup plus simple. Parce que la correspondance est par position, on peut faire une affectation directe de colonne:
df1 <- data.frame(a1 = c("b2","c2","abc2"), b1 = c("bb2","cc2","d2"), stringsAsFactors = FALSE)
df2 <- data.frame(sale = c("sale","sale2","sale3"), b1 = c("b2","c2","d2"), stringsAsFactors = FALSE)
df1$sale <- df2$sale
joined <- merge(df2,df1,by = 'sale')
joined$new <- ifelse(joined$b1.x == joined$b1.y, joined$b1.x, joined$b1.y)
joined[,c(1,5)]
#> sale new
#> 1 sale bb2
#> 2 sale2 cc2
#> 3 sale3 d2
Créé le 23/02/2020 par le paquet reprex (v0.3.0)
Après avoir supprimé les facteurs, vous pouvez simplement faire df2 $ b1 <- ifelse (df2 $ b1 == df1 $ a1, df1 $ b1, df2 $ b1)
@WaltS très vrai. c’est la solution de loin la plus directe. .
@WaltS voulez-vous en faire une réponse ou dois-je modifier la mienne?
Vous avez répondu en premier. J'ai juste simplifié un peu les choses.
Je ne sais pas si cela fonctionne pour vous, mais beaucoup plus facile si vous utilisez le dplyr , comme mentionné par tjebo :
df2 <- data.frame(a1 = c("sale","sale2","sale3"),b1 = c("b2","c2","d2"),
stringsAsFactors = F)
Sortie
new_df
a1 b1
1 sale b2
2 sale2 c2
3 sale3 abc2
case_when est la manière dplyr de créer if-else construction.
Remarque
Vous devez avoir les colonnes comme n'importe quoi, sauf
facteurs, pour que cela fonctionne. Ajoutez simplementstringsAsFactors = F, tout en formant le dataframe, comme ci-dessous.
new_df <- df2 %>% mutate(b1 = case_when(b1 == df1$a1 ~ b1, b1 != df1$a1 ~ df1$a1))
Voici une solution de base R, utilisant merge + ifelse , c'est-à-dire
> dfout a1.y b1 1 sale bb2 2 sale2 cc2 3 sale3 d2
telle que
dfout <- rev(within(merge(df1,df2,by.x = "a1",by.y = "b1",all.y = TRUE),
b1 <- ifelse(is.na(b1),as.character(a1),as.character(b1)))[-1])
voulez-vous dire faire correspondre les valeurs par position?
Je veux dire des valeurs correspondantes si elles correspondent à l'ancienne valeur correspondante sinon l'ancienne valeur de b1 de df2 pour rester
désolé, pas encore clair - comment savoir à quelle ancienne valeur appartiennent les nouvelles? Est-ce par sa position (ligne) dans le bloc de données?
oui par sa position @Tjebo
Vérifiez la réponse mise à jour - tout le mérite revient à @WaltS