R 将数据帧中沿指定列的所有可能的从左到右对角线按组求和?
假设我有这样的东西:R 将数据帧中沿指定列的所有可能的从左到右对角线按组求和?,r,R,假设我有这样的东西: 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,
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组求和的“对角线”,作为示例:
您可以使用diag()拆分data.frame并对对角线求和。一旦每个组都有了这个对角线和,它就通过调用组将它们放回data.frame 第四组应该是零?还是我遗漏了什么
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
这里是另一个解决方案,我们使用
行
和列
索引来获得所有可能的对角线组合。使用by
按组拆分,并将其与原始数据帧合并
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
max_diag group 4有三个1,从binary2-binary4开始,都是对角的,我不关心起始点,我将在文章中澄清,然后取主对角线的和。在示例数据中,主对角线的和总是最大的,但如果不是这样,例如,如果binary1的倒数第二个值更改为1,则want
列将不同于最大对角线和。Hi@IceCreamToucan,非常感谢您指出这一点!我忘了转置。我已经编辑了我的答案,将其包括在内。nice row col,此外,这一条似乎更适合于第7组:dft这很好,但是有没有办法指定只对二进制变量求和(即,如果我在binary1和group之间有很多其他字符变量?)我可以在以后合并这些变量,但不希望这样to@biostatguy12您可以选择所需的列merge(df,stack(by(df[2:5],df$group,max_diag)),by.x=“group”,by.y=“ind”)
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