按组将数据帧中指定列上所有可能的左到右对角线相加?

时间:2019-12-31 00:22:55

标签: r

假设我有这样的东西:

MEMBER OF

我想对组(即组1、2 4和6)中所有可能的从左到右对角线求和,并返回最大和。这也在数据帧中,因此我想指定仅沿binary1-binary4求和。有人知道这是否可能吗?

这是我想要的输出:

df<-data.frame(group=c(1, 1,2, 2, 2, 4,4,4,4,6,6,6), 
               binary1=c(1,0,1,0,0,0,0,0,0,0,0,0),
               binary2=c(0,1,0,1,0,1,0,0,0,0,1,1),
               binary3=c(0,0,0,0,1,0,1,0,0,0,0,0),
               binary4=c(0,0,0,0,0,0,0,1,0,0,0,0))

我已经圈出了我想在此图中的第4组加起来的“对角线”作为示例:

enter image description here

2 个答案:

答案 0 :(得分:4)

这是另一个解决方案,其中我们使用rowcol索引来获取对角线的所有可能组合。使用by按组划分,然后merge与原始数据框一起使用。

max_diag <- function(x) max(sapply(split(as.matrix(x), row(x) - col(x)), sum))

merge(df, stack(by(df[-1], df$group, max_diag)), by.x = "group", by.y = "ind")

#   group binary1 binary2 binary3 binary4 values
#1      1       1       0       0       0      2
#2      1       0       1       0       0      2
#3      2       1       0       0       0      3
#4      2       0       1       0       0      3
#5      2       0       0       1       0      3
#6      4       0       1       0       0      3
#7      4       0       0       1       0      3
#8      4       0       0       0       1      3
#9      4       0       0       0       0      3
#10     6       0       0       0       0      1
#11     6       0       1       0       0      1
#12     6       0       1       0       0      1

答案 1 :(得分:2)

您可以分割data.frame并使用diag()对角线求和。一旦每个组都有这个对角线总和,就可以通过调用该组将它们放回到data.frame中。

第4组应该为零?还是我错过了什么:

DIAG = by(df[,-1],df$group,function(i)sum(diag(as.matrix(i))))
df$want = DIAG[as.character(df$group)]

如果我的定义正确,我们将定义一个函数来计算主对角线的总和:

main_diag = function(m){
sapply(1:(ncol(m)-1),function(i)sum(diag(m[,i:ncol(m)])))
}

感谢@IceCreamToucan对此进行了更正。然后我们考虑所有主要对角线的最大值及其转置:

DIAG = by(df[,-1],df$group,function(i){
  i = as.matrix(i)
  max(main_diag(i),main_diag(t(i)))
})

df$want = DIAG[as.character(df$group)]

   group binary1 binary2 binary3 binary4 want
1      1       1       0       0       0    2
2      1       0       1       0       0    2
3      2       1       0       0       0    3
4      2       0       1       0       0    3
5      2       0       0       1       0    3
6      4       0       1       0       0    3
7      4       0       0       1       0    3
8      4       0       0       0       1    3
9      4       0       0       0       0    3
10     6       0       0       0       0    1
11     6       0       1       0       0    1
12     6       0       1       0       0    1