如果在其他行中重复,则使用R中的dplyr添加列

时间:2016-08-18 09:28:25

标签: r dplyr

如果在其他行中重复,我想根据条件向数据框添加一列。我的数据框如下:

group label value   newColumn
1     1     3
1     2     4
1     3     3
1     4     5
1     5     4
2     1     6
2     2     3
2     3     9
2     4     6
2     5     1
2     6     3

我想添加一列:

if df$value[i] is duplicated and df$value[i] is the original, set newColumn[i] to 0; 
if df$value[i] is duplicated and df$value[i] is the duplicate, set newColumn[i] to the label of the original;
if df$value[i] is not duplicated, set df$newColumn[i] to 0.

例如:

df$value[1] = 3 is duplicated, but it is the original, so we set newColumn[1] = 0;
df$value[3] = 3 is duplicated, and it is the duplicate, so we set newColumn[3] = 1 (=df$label[1]);

这是我的代码:

library(dplyr)

df <- df %>%
group_by(group) %>%
mutate(
newColumn = ifelse(row_number() == min( which(duplicated(value) | duplicated(value, fromLast = TRUE)) ), 
                           label[max( which(duplicated(value) | duplicated(value, fromLast = TRUE)))],
                           0)
)

但它没有帮助。有什么建议吗?提前谢谢!

2 个答案:

答案 0 :(得分:2)

以下是使用ave()的解决方案:

df$newColumn <- ave(df$label,df$value,FUN=function(x) c(0L,rep(x[1L],length(x)-1L)))
df;
##    group label value newColumn
## 1      1     1     3         0
## 2      1     2     4         0
## 3      1     3     3         1
## 4      1     4     5         0
## 5      1     5     4         2
## 6      2     1     6         0
## 7      2     2     3         1
## 8      2     3     9         0
## 9      2     4     6         1
## 10     2     5     1         0
## 11     2     6     3         1

ave()根据第二个参数将第一个参数分成组,并为每个组调用一次lambda。因此,例如,对于df$value等于3的所有行,ave()将构造一个由这些行中的所有df$label值组成的向量,并使用{{1}调用lambda等于那个向量。 lambda调用的返回值应该包含与参数x相同数量的元素(或者它将根据需要进行回收以实现它)。

然后将lambda的所有调用的返回值组合成一个最终向量,每个返回值的每个元素放置在与输入的对应位置相对应的位置。这允许我们按组构建最终列向量。由于您的问题需要为每个组中的第一个元素返回零,并且每个组中的所有后续元素都返回原始标签值,因此我们可以通过将零与原始标签值组合在一起来轻松地在lambda中构建该子向量,以覆盖剩余的组矢量。

答案 1 :(得分:2)

我们也可以使用data.table

library(data.table)
setDT(df)[, newColumn := c(0, rep(label[1L], .N-1)) , value]