Dans df1, je dois remplacer les valeurs de msec par les valeurs correspondantes dans df2.
df1 <- data.frame(ID=c('rs', 'rs', 'rs', 'tr','tr','tr'), cond=c(1,1,2,1,1,2),
block=c(2,2,4,2,2,4), correct=c(1,0,1,1,1,0), msec=c(456,678,756,654,625,645))
df2 <- data.frame(ID=c('rs', 'rs', 'tr','tr'), cond=c(1,2,1,2),
block=c(2,4,2,4), mean=c(545,664,703,765))
Dans df1, if correct==0
, alors référence df2
avec les valeurs correspondantes de ID
, cond
et block
. Remplacez la valeur de msec
dans df1
par la valeur correspondante pour mean
dans df2
.
Par exemple, la deuxième ligne de df1 contient correct==0
. Ainsi, dans df2
trouvez la ligne correspondante où ID=='rs'
, cond==1
, block==2
et utilisez la valeur de mean (mean=545
) pour remplacer la valeur de msec ( msec=678
). Notez que dans df1, les combinaisons d'ID, de bloc et de cond peuvent se répéter, mais chaque combinaison ne se produit qu'une seule fois dans df2.
2 réponses
Utilisation du package data.table
:
# load the 'data.table' package
library(data.table)
# convert the data.frame's to data.table's
setDT(df1)
setDT(df2)
# update df1 by reference with a join with df2
df1[df2[, correct := 0], on = .(ID, cond, block, correct), msec := i.mean]
Qui donne:
> df1
ID cond block correct msec
1: rs 1 2 1 456
2: rs 1 2 0 545
3: rs 2 4 1 756
4: tr 1 2 1 654
5: tr 1 2 1 625
6: tr 2 4 0 765
Remarque: le code ci-dessus mettra à jour df1
au lieu de créer une nouvelle trame de données, qui est plus efficace en mémoire.
Une option serait d'utiliser la base R avec un interaction()
et un match()
. Que diriez-vous:
df1[which(df1$correct==0),"msec"] <- df2[match(interaction(df1[which(df1$correct==0),c("ID","cond","block")]),
interaction(df2[,c("ID","cond", "block")])),
"mean"]
df1
# ID cond block correct msec
#1 rs 1 2 1 456
#2 rs 1 2 0 545
#3 rs 2 4 1 756
#4 tr 1 2 1 654
#5 tr 1 2 1 625
#6 tr 2 4 0 765
Nous remplaçons les colonnes correct == 0
par leurs lignes correspondantes dans df2$mean
Modifier: Une autre option serait une fusion SQL qui pourrait ressembler à:
library(sqldf)
merged <- sqldf('SELECT l.ID, l.cond, l.block, l.correct,
case when l.correct == 0 then r.mean else l.msec end as msec
FROM df1 as l
LEFT JOIN df2 as r
ON l.ID = r.ID AND l.cond = r.cond AND l.block = r.block')
merged
ID cond block correct msec
1 rs 1 2 1 456
2 rs 1 2 0 545
3 rs 2 4 1 756
4 tr 1 2 1 654
5 tr 1 2 1 625
6 tr 2 4 0 765
De nouvelles questions
r
R est un langage de programmation et un environnement logiciel libres et open source pour le calcul statistique, la bioinformatique, la visualisation et le calcul général. Veuillez fournir des exemples minimaux et reproductibles ainsi que le résultat souhaité. Utilisez dput () pour les données et spécifiez tous les packages non basiques avec des appels à library (). N'incorporez pas d'images pour les données ou le code, utilisez plutôt des blocs de code en retrait. Pour les questions relatives aux statistiques, utilisez https://stats.stackexchange.com.