将列和添加到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],数据将保持不变。哦,我刚刚在您的帖子中看到我忘记了括号。没有关系。