将列和添加到dataframe行中,并在伪值上设置条件

将列和添加到dataframe行中,并在伪值上设置条件,r,dataframe,apply,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

我希望将数据帧中的列的总和一次添加一行,条件是另一列有一个二进制变量

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

以下是一个例子:

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

我之前问过一个简化版本()的问题,在这个版本中,我只添加了上面所有的值,没有条件。是否有方法合并此条件?

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

setDT(your_data)
your_data[, c("var1", "var2") := .(cumsum(var1), cumsum(var2)), by = dummy]
(注意:这假设您的文本是准确的,而您的示例是不正确的:它在
dummy
列中按连续相等的值分组。)

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

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

如果您只想按虚拟列分组,忽略连续性,那么您的问题,您可以这样做:

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

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

setDT(your_data)
your_data[, c("var1", "var2") := .(cumsum(var1), cumsum(var2)), by = dummy]
(注意:这假设您的文本是准确的,而您的示例是不正确的:它在
dummy
列中按连续相等的值分组。)

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

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

如果您只想按虚拟列分组,忽略连续性,那么您的问题,您可以这样做:

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

我不认为用一个简单的函数就可以做到这一点,至少根据我的经验是不行的。因此,我建议编写如下函数:

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,]
            }    
        }
    }
}

sum_new_df我不认为用一个简单的函数就可以做到这一点,至少根据我的经验是不行的。因此,我建议编写如下函数:

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,]
            }    
        }
    }
}

sum\u new\u df您可以使用
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))
使用什么:
您可以使用
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))
使用什么:
这里已经有一些很好的答案了。这是一个使用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  
数据帧(虚拟=c(1L,0L,0L,1L),var1=c(1L,2L,4L,6L),var2=c(100L,20L,30L,400L))%>%
分组依据(虚拟)%>%
突变_all(funs(cumsum))
#一个tibble:4x3
#分组:假人[2]
虚拟var1 var2
1  1.00  1.00 100  
2  0     2.00  20.0
3  0     6.00  50.0
4  1.00  7.00 500  

这里已经有一些不错的答案了。这是一个使用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  
数据帧(虚拟=c(1L,0L,0L,1L),var1=c(1L,2L,4L,6L),var2=c(100L,20L,30L,400L))%>%
分组依据(虚拟)%>%
突变_all(funs(cumsum))
#一个tibble:4x3
#分组:假人[2]
虚拟var1 var2
1  1.00  1.00 100  
2  0     2.00  20.0
3  0     6.00  50.0
4  1.00  7.00 500  


您可以使用此处提到的有效的
ave
功能。是否有一种优雅的方法将其应用于整个数据帧。有了ave,我走到了这一步:df$newVar我可以在apply中使用它作为我选择的函数吗?相应的行具有相同的值?你的意思是如果第5行中的虚拟对象是1,那么var1将是x4+x1+x5,var2是y4+y5+y1?或者具有相同值的dummy的所有行都具有相同的对应值?它们是两种不同的算法。你的
ave
答案看起来很完美。您想如何应用它?您是否担心扩展到两个以上的列而不将它们全部写出来?您可以使用这里提到的
ave
函数,这是有效的。是否有一种优雅的方法将其应用于整个数据帧。有了ave,我走到了这一步:df$newVar我可以在apply中使用它作为我选择的函数吗?相应的行具有相同的值?你的意思是如果第5行中的虚拟对象是1,那么var1将是x4+x1+x5,var2是y4+y5+y1?或者具有相同值的dummy的所有行都具有相同的对应值?它们是两种不同的算法。你的
ave
答案看起来很完美。您想如何应用它?您是否担心在不将数据全部写出的情况下扩展到两列以上?请参阅我对两行
数据的回答。表
版本请参阅我对两行
数据的回答。表
版本好的回答,我很少使用数据。表,图我应该熟悉这一点。是否可以在不写所有列名的情况下使用下面的group by伪列(我有50多列)。因此,您的下面的替代方案(group by伪列)工作得很好,但我在传递列向量时无法实现这一点。例如,如果我定义:cols=c(“var1”,“var2”),然后运行您的_数据[,cols:=(cumsum(var1),cumsum(var2)),by=dummy],数据将保持不变。哦,我刚刚在您的帖子中看到我忘记了括号。没关系。回答得好,我很少使用data.table,图我应该熟悉它。是否可以在不写所有列名的情况下(我有50多列)按伪列使用较低的分组。因此,您的较低备选方案(按伪列分组)工作得很好,但在传递列向量时,我无法实现这一点。例如,如果我定义:cols=c(“var1”,“var2”),然后运行您的_数据[,cols:=(cumsum(var1),cumsum(var2)),by=dummy],数据将保持不变。哦,我刚刚在您的帖子中看到我忘记了括号。没有关系。