R 如何在数据帧的对角线上求和

R 如何在数据帧的对角线上求和,r,sum,dataframe,diagonal,R,Sum,Dataframe,Diagonal,假设我有这个数据框: 1 2 3 4 100 8 12 5 14 99 1 6 4 3 98 2 5 4 11 97 5 3 7 2 在上述数据框中,这些值表示对(100,1)、(99,1)等进行的观察次数 在我的上下文中,对角线具有相同的含义: 1 2 3 4 100 A B C D 99 B C D E 98 C

假设我有这个数据框:

     1   2   3   4      
100  8   12  5   14 
99   1   6   4   3   
98   2   5   4   11  
97   5   3   7   2   
在上述数据框中,这些值表示对
(100,1)、(99,1)
等进行的观察次数

在我的上下文中,对角线具有相同的含义:

     1   2   3   4
100  A   B   C   D 
99   B   C   D   E  
98   C   D   E   F 
97   D   E   F   G
如何在第一个数据帧中对对角线进行求和(即,对类似字母的计数求和)

这将产生:

group  sum
A      8
B      13
C      13
D      28
E      10
F      18
G      2
例如,
D
5+5+4+14

您可以使用
row()
col()
来标识行/列关系

m <- read.table(text="
    1   2   3   4      
100  8   12  5   14 
99   1   6   4   3   
98   2   5   4   11  
97   5   3   7   2")

vals <- sapply(2:8,
       function(j) sum(m[row(m)+col(m)==j]))

as.matrix()
是使
split()
正常工作所必需的…

这里有一个使用
stack()
aggregate()
的解决方案,尽管它需要第二个data.frame包含字符向量,而不是因子(可以使用
lappy(df2,as.character)
):


df1使用bgoldst对
df1
df2

sapply(unique(c(as.matrix(df2))),function(x) sum(df1[df2==x]))
给予


(不是您想要的格式,但可能没问题…

另一个
聚合
变体,避免了公式接口,这实际上使本例中的问题变得复杂:

aggregate(list(Sum=unlist(dat)), list(Group=LETTERS[c(row(dat) + col(dat))-1]), FUN=sum)

#  Group Sum
#1     A   8
#2     B  13
#3     C  13
#4     D  28
#5     E  10
#6     F  18
#7     G   2

这是矩阵还是数据帧?(矩阵更容易在)data.frame上执行此操作,但将其转换为矩阵并返回到data.frame,如@Ben Bolker的回答中所述。类似:忘了提及我的解决方案假设您已设置
选项(stringsAsFactors=FALSE)
。需要将其转换为矩阵的逻辑是什么(而不是留在data.frame中)为了做到这一点,@BenBolker-row和col处理所有2维“矩阵式”对象,包括矩阵、数据帧、表格等。另一个非常类似的对象:
data.frame(vals=tapply(as.matrix(m),(字母[row(m)+col(m)-1]),sum))
df1 <- data.frame(a=c(8,1,2,5), b=c(12,6,5,3), c=c(5,4,4,7), d=c(14,3,11,2) );
df2 <- data.frame(a=c('A','B','C','D'), b=c('B','C','D','E'), c=c('C','D','E','F'), d=c('D','E','F','G'), stringsAsFactors=F );
aggregate(sum~group,data.frame(sum=stack(df1)[,1],group=stack(df2)[,1]),sum);
##   group sum
## 1     A   8
## 2     B  13
## 3     C  13
## 4     D  28
## 5     E  10
## 6     F  18
## 7     G   2
sapply(unique(c(as.matrix(df2))),function(x) sum(df1[df2==x]))
#A  B  C  D  E  F  G 
#8 13 13 28 10 18  2 
aggregate(list(Sum=unlist(dat)), list(Group=LETTERS[c(row(dat) + col(dat))-1]), FUN=sum)

#  Group Sum
#1     A   8
#2     B  13
#3     C  13
#4     D  28
#5     E  10
#6     F  18
#7     G   2