简体   繁体   English

r - 根据另一列中的匹配复制值

[英]r - copy value based on match in another column

In this data frame: 在此数据框中:

Item <- c("A","B","A","A","A","A","A","B")
Trial <- c("Fam","Fam","Test","Test","Test","Test","Test","Test")
Condition <-c("apple","cherry","Trash","Trash","Trash","Trash","Trash","Trash")
ID <- c(rep("01",8))


df <- data.frame(cbind(Item,Trial,Condition,ID))

I would like to replace the "Trash" value of df$condition at df$Trial == "Test" . 我想在df$Trial == "Test"替换df$condition的“Trash”值。 The new value of df$condition should be a copy df$condition at df$Trial == "Fam" , based on a match of Fam and Test Trials in df$Item . 根据df$Item中Fam和Test Trials的匹配, df$condition的新值应该是df$Trial == "Fam"的副本df$condition

So my final data frame should look like this 所以我的最终数据框应该是这样的

  Item Trial Condition ID
1    A   Fam     apple 01
2    B   Fam    cherry 01
3    A  Test     apple 01
4    A  Test     apple 01
5    A  Test     apple 01
6    A  Test     apple 01
7    A  Test     apple 01
8    B  Test    cherry 01

Ultimately I would like to do this for unique ID's in my original data frame. 最后,我想在原始数据框中为唯一ID执行此操作。 So I guess I will have to apply the function within ddply or so later on. 所以我想我将不得不在ddply应用该函数。

You could do a self binary join on df when Trial != "Test" and update the Condition column by reference using the data.table package, for instance 您可以在Trial != "Test"时在df上执行自我二进制连接 ,并使用data.table通过引用更新Condition列,例如

library(data.table) ## V 1.9.6+
setDT(df)[df[Trial != "Test"], Condition := i.Condition, on = c("Item", "ID")]
df
#    Item Trial Condition ID
# 1:    A   Fam     apple 01
# 2:    B   Fam    cherry 01
# 3:    A  Test     apple 01
# 4:    A  Test     apple 01
# 5:    A  Test     apple 01
# 6:    A  Test     apple 01
# 7:    A  Test     apple 01
# 8:    B  Test    cherry 01

Or (with some modification of @docendos) suggestion, simply 或者(对@docendos进行一些修改)建议,简单地说

setDT(df)[, Condition := Condition[Trial != "Test"], by = .(Item, ID)]

Here is an option using dplyr 这是使用dplyr的选项

library(dplyr)
distinct(df) %>% 
    filter(Trial=='Fam') %>% 
    left_join(df, ., by = c('Item', 'ID')) %>% 
    mutate(Condition = ifelse(Condition.x=='Trash',
            as.character(Condition.y), as.character(Condition.x))) %>% 
    select(c(1,2,4,7))

Or as suggested by @docendodiscimus 或者按照@docendodiscimus的建议

df %>% 
    group_by(ID, Item) %>%
    mutate(Condition = Condition[Condition != "Trash"])

You could also just create a for-loop and loop through all the values that need to be changed. 您还可以创建一个for循环并循环遍历所有需要更改的值。 This setup makes it easy to add other items and/or change the type of condition later on. 此设置可以轻松添加其他项目和/或稍后更改条件类型。

> for(i in 1:nrow(df)) {
>     
>     if(df[i, 1] == "A") {
>         df2[i, 3] <- "apple"
>     }
>     else if(df[i, 1] == "B") {
>         df2[i, 3] <- "cherry"
>     }
> }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM