2015-08-25 64 views
6

我有一个看起来像下面这样的数据帧:值分配给组基于条件

> df = data.frame(group = c(1,1,1,2,2,2,3,3,3), 
       date = c(1,2,3,4,5,6,7,8,9), 
       value = c(3,4,3,4,5,6,6,4,9)) 
> df 
    group date value 
1  1 1  3 
2  1 2  4 
3  1 3  3 
4  2 4  4 
5  2 5  5 
6  2 6  6 
7  3 7  6 
8  3 8  4 
9  3 9  9 

我希望创建一个包含每个与该值相关联组的日期值的新列值列中的“4”。

以下数据框显示了我希望完成的工作。

group date value newValue 
1  1 1  3  2 
2  1 2  4  2 
3  1 3  3  2 
4  2 4  4  4 
5  2 5  5  4 
6  2 6  6  4 
7  3 7  6  8 
8  3 8  4  8 
9  3 9  9  8 

正如我们所看到的,组1具有newValue“2”,因为那是与值“4”相关联的日期。同样,第二组有新值4和第三组有新值8.

我假设有一个简单的方法来使用ave()或dplyr/data.table函数执行此操作,但我一直没有成功许多尝试。

+0

@DavidArenburg你说得对!我只是修好了它 –

回答

11

这里有一个快速data.table一个

library(data.table) 
setDT(df)[, newValue := date[value == 4L], by = group] 
df 
# group date value newValue 
# 1:  1 1  3  2 
# 2:  1 2  4  2 
# 3:  1 3  3  2 
# 4:  2 4  4  4 
# 5:  2 5  5  4 
# 6:  2 6  6  4 
# 7:  3 7  6  8 
# 8:  3 8  4  8 
# 9:  3 9  9  8 

下面是一个类似dplyr版本

library(dplyr) 
df %>% 
    group_by(group) %>% 
    mutate(newValue = date[value == 4L]) 

或过滤后的数据使用merge一个可能的基础R解决方案(将需要一些之后重命名)

merge(df, df[df$value == 4, c("group", "date")], by = "group") 
+1

正是我所需要的。谢谢! –

+0

@David Arenburg,请在这里稍微调整一下,https://stackoverflow.com/questions/47716479/data-frame-modification-in-r –

1

这里是使用碱R选项

df$newValue = rep(df$date[which(df$value == 4)], table(df$group)) 

另一替代lapply

do.call(rbind, lapply(split(df, df$group), 
    function(x){x$newValue = rep(x$date[which(x$value == 4)], 
        each = length(x$group)); x})) 

# group date value newValue 
#1.1  1 1  3  2 
#1.2  1 2  4  2 
#1.3  1 3  3  2 
#2.4  2 4  4  4 
#2.5  2 5  5  4 
#2.6  2 6  6  4 
#3.7  3 7  6  8 
#3.8  3 8  4  8 
#3.9  3 9  9  8 
1

一个更base R路径:

df$newValue <- ave(`names<-`(df$value==4,df$date), df$group, FUN=function(x) as.numeric(names(x)[x])) 
df 
    group date value newValue 
1  1 1  3  2 
2  1 2  4  2 
3  1 3  3  2 
4  2 4  4  4 
5  2 5  5  4 
6  2 6  6  4 
7  3 7  6  8 
8  3 8  4  8 
9  3 9  9  8 
10  3 11  7  8 

我用可变长度组的测试。我将date列指定为逻辑索引value的名称等于4.然后按组标识值。

数据

df = data.frame(group = c(1,1,1,2,2,2,3,3,3,3), 
       date = c(1,2,3,4,5,6,7,8,9,11), 
       value = c(3,4,3,4,5,6,6,4,9,7))