在虚拟的条件下以数据帧的方式添加列和

时间:2018-02-04 01:44:54

标签: r dataframe apply

我想一次添加一行数据帧的总和,条件是另一列有二进制变量。

因此,对于每一行,我想计算相应行中二进制变量具有相同值的所有行的上面整列的总和。

以下是一个例子:

dummy var1  var2
1     x1     y1
0     x2     y2
0     x3     y3
1     x4     y4

我的目标是获得这个:

dummy var1     var2
1     x1       y1
0     x2       y2
0     x3+x2    y3+y2
1     x4+x1    y4+y1

我之前已经问过这个问题的简化版本(Adding columns sums in dataframe row wise),我只是在没有条件的情况下添加上面的所有值。有没有办法纳入这个条件?

4 个答案:

答案 0 :(得分:4)

data.table::rleid会为您提供所需的分组。如果将数据框转换为data.table,则如下所示:

(注意:这假定您的文字准确且您的示例不正确:它在dummy列中按连续相等的值进行分组。)

library(data.table)
setDT(your_data)
your_data[, id := rleid(dummy)][
  , c("var1", "var2") := .(cumsum(var1), cumsum(var2)), by = id
]

如果您需要对一堆列执行此操作,请按上述设置id,定义列向量,然后:

cols = c("var1", "var2", "var3", ...)
your_data[, (cols) := lapply(.SD, cumsum), by = id, .SD = cols]

如果你只想按虚拟列分组,忽略连续性,那么你的问题is an exact duplicate of this one就可以这样做了:

setDT(your_data)
your_data[, c("var1", "var2") := .(cumsum(var1), cumsum(var2)), by = dummy]

答案 1 :(得分:3)

您可以使用Reduce

fun=function(x)Reduce(function(x,y)paste0(y,"+",x),x,accumulate = T)
sapply(dat[-1],function(x)ave(x,dat[,1],FUN = fun))
     var1    var2   
[1,] "x1"    "y1"   
[2,] "x2"    "y2"   
[3,] "x3+x2" "y3+y2"
[4,] "x4+x1" "y4+y1"

如果这些只是值,那么你可以这样做:

#Example data
dat2=data.frame(dummy=dat[,1],var1=c(1,2,10,20),var2=c(10,20,50,3))

使用方法:

sapply(dat2[-1],function(x)ave(x,dat2[,1],FUN=cumsum))
     var1 var2
[1,]    1   10
[2,]    2   20
[3,]   12   70
[4,]   21   13

答案 2 :(得分:2)

这里有一些好的答案。这是使用dplyr的解决方案:

data.frame(dummy = c(1L,0L,0L,1L), var1 = c(1L,2L,4L,6L), var2 = c(100L,20L,30L,400L)) %>%
    group_by(dummy) %>%
    mutate_all(funs(cumsum))

# A tibble: 4 x 3
# Groups:   dummy [2]
  dummy  var1  var2
  <dbl> <dbl> <dbl>
1  1.00  1.00 100  
2  0     2.00  20.0
3  0     6.00  50.0
4  1.00  7.00 500  

答案 3 :(得分:1)

嗯,我不认为你可以用一个简单的功能来做到这一点,至少不是根据我的经验。所以我建议写一个函数如下:

sum_new_df  <- function(df){
    new_df <- df[,-1]
    for (i in 1:nrow(df)){
        for (j in (i+1):nrow(df)){
            if (df$dummy[i] == df$dummy[j]){
                new_df[j,] <- df[,-1][j,] + df[,-1][j,]
            }    
        }
    }
}

此函数只能通过增加行号来总结相同虚拟对象的行值。因此,如果这是一个大型data.frame,那么该值将类似于金字塔。