J'ai quelques données; qui ressemble à; p> J'ai besoin de modifier la valeur de tout Mes données réelles a environ 80 Y a-t-il un moyen simple de faire cela? p> merci p> p> * _Score code> colonne à zéro si la valeur de la colonne code> de la colonne de cette ligne correspond à la première partie du nom de la colonne code> _ _ (code> doit donc ressembler aux données résultantes. Ceci; p>
* _ score code> colonnes. p>
4 Réponses :
Une possibilité impliquant dplyr code> et
titsy code> pourrait être:
Voici une idée via dplyr code>. Nous nous convertissons au format long, utilisez une simple regex pour extraire la première partie des noms et simplement comparer avec
code code>. Une fois terminé, nous
client code CN_SCORE CS_SCORE VN_SCORE
1 123 CN 0.0000000 0.2828444 -0.75224398
2 124 <NA> -0.5815069 -0.1053807 -0.03881512
3 125 VN -0.4489411 -1.3682422 0.00000000
4 126 CS -2.4349032 0.0000000 0.75258368
5 127 PO -1.7483976 1.3793556 -0.59094268
6 128 CS 0.2732683 0.0000000 -0.98756547
7 129 <NA> -0.9394162 -1.5184852 -0.20126150
8 130 BE -0.8731287 -0.2340674 -0.68192984
9 131 VN 0.3726439 2.1826383 0.00000000
10 132 CN 0.0000000 3.0400324 -0.33033666
Utilisation de la base R, une approche vectorisée serait de créer une matrice de ligne / colonne pour remplacer les valeurs dans le Dataframe. Nous supprimons tout après le soulignement et correspondant code> avec les noms de colonne pour obtenir l'index de la colonne. Pour obtenir l'indice de ligne, nous trouvons
code code> qui n'est pas
na code> et est inclus dans
cols code>.
cols <- sub("_.*", "", names(df))
inds <- which(!is.na(df$code) & df$code %in% cols)
df[cbind(inds, match(df$code[inds],cols))] <- 0
df
# client CN_SCORE VN_SCORE CS_SCORE code
#1 123 0.0000000 -0.23627957 -1.3108015 CN
#2 124 -1.0959963 -0.19717589 1.9972134 <NA>
#3 125 0.0377884 0.00000000 0.6007088 VN
#4 126 0.3104807 0.08473729 0.0000000 CS
#5 127 0.4365235 0.75405379 -0.6111659 PO
#6 128 -0.4583653 -0.49929202 0.0000000 CS
#7 129 -1.0633261 0.21444531 2.1988103 <NA>
#8 130 1.2631852 -0.32468591 1.3124130 BE
#9 131 -0.3496504 0.00000000 -0.2651451 VN
#10 132 0.0000000 -0.89536336 0.5431941 CN
Si vous vectorisez GREPL, vous pouvez obtenir une matrice qui est vraie si le nom de la colonne (la première partie) est trouvé dans code code> et false si non. Inverser les trues et les falmes et multiplier la matrice par les colonnes d'origine donne le résultat souhaité.
cols <- grep('_SCORE', names(df), value = TRUE)
df[cols] <- df[cols]*!Vectorize(grepl, 'pattern')(substr(cols, 1, 2), df$code)
df
# client CN_SCORE VN_SCORE CS_SCORE code
# 1 123 0.0000000 -0.1119434 1.02750890 CN
# 2 124 0.3511996 0.2970757 1.11384814 <NA>
# 3 125 -0.1495255 0.0000000 1.29628327 VN
# 4 126 -0.3645585 0.3932262 0.00000000 CS
# 5 127 -0.2272243 1.4857947 -2.12265618 PO
# 6 128 -0.1615514 0.1449268 0.00000000 CS
# 7 129 0.5020869 1.6921847 0.01622139 <NA>
# 8 130 0.6160465 0.4361738 1.62195307 BE
# 9 131 -2.8887592 0.0000000 -0.68922501 VN
# 10 132 0.0000000 -0.5525893 -0.13748636 CN