R 按另一个共享因子交叉列表并汇总因子
给定数据:R 按另一个共享因子交叉列表并汇总因子,r,R,给定数据: D=data.frame(f1=c(“a”、“a”、“b”、“b”、“b”),f2=c(“X”、“Y”、“X”、“Y”、“Z”),val=1:5) 如何交叉制表f2对,使表中的每个元素对应于共享相同f1的每对f2的val之和 # desired result (matrix diagonal could be either NA or 0): X Y Z X NA 10 8 Y 10 NA 9 Z 8 9 NA 例如,X和Y共享a,因此(1+2)也
D=data.frame(f1=c(“a”、“a”、“b”、“b”、“b”),f2=c(“X”、“Y”、“X”、“Y”、“Z”),val=1:5)
如何交叉制表f2
对,使表中的每个元素对应于共享相同f1
的每对f2
的val
之和
# desired result (matrix diagonal could be either NA or 0):
X Y Z
X NA 10 8
Y 10 NA 9
Z 8 9 NA
例如,X
和Y
共享a
,因此(1+2)
也共享b
因此(3+4)
。因此结果[1,2]=(1+2)+(3+4)=10
。另外,结果[2,3]=4+5=9等
它有助于将f1
视为股票,f2
视为投资组合,val
视为每个投资组合中每个股票的投资持有量。由此得出的表格代表了“羊群效应”——不同投资组合倾向于持有相同股票的程度
是否有任何类似于表格
或扫描
的“智能”R
功能适合该任务?这是一个非常具体的操作。可能只是编写自己的函数。例如:
ff<-function(x,y){
if(x==y)
return(NA)
f1vals<-intersect(D$f1[D$f2==x],D$f1[D$f2==y])
sum(D$val[D$f1 %in% f1vals & D$f2 %in% c(x,y)])
}
outer(unique(D$f2),unique(D$f2),Vectorize(ff))
# [,1] [,2] [,3]
#[1,] NA 10 8
#[2,] 10 NA 9
#[3,] 8 9 NA
ff试试:
我终于找到了在数据中使用笛卡尔自联接的解决方案。table
包和dcast
使用成对和表:
library(data.table)
D = data.table(f1=factor(c("a","a","b","b","b")), f2=factor(c("X","Y","X","Y","Z")), val=1:5)
setkey(D, f1)
DD = D[D, allow.cartesian=TRUE]
DD[, pair_sum := val + i.val]
DD[f2==i.f2, pair_sum := NA_real_]
dcast.data.table(DD, f2 ~ i.f2, fun.aggregate = sum, value.var="pair_sum")
# f2 X Y Z
# 1: X NA 10 8
# 2: Y 10 NA 9
# 3: Z 8 9 NA
另一个base
解决方案可能类似于:
m<-subset(merge(D,D,"f1"),f2.x!=f2.y)
m<-aggregate(val.x~f2.x+f2.y,data=m,sum)
m<-xtabs(val.x~f2.x+f2.y, data=m)
m+t(m)
f2.x
f2.y X Y Z
X 0 10 8
Y 10 0 9
Z 8 9 0
m一旦在短时间内发布了多个答案,投票最多的答案将被接受。谢谢你的回答。
library(data.table)
D = data.table(f1=factor(c("a","a","b","b","b")), f2=factor(c("X","Y","X","Y","Z")), val=1:5)
setkey(D, f1)
DD = D[D, allow.cartesian=TRUE]
DD[, pair_sum := val + i.val]
DD[f2==i.f2, pair_sum := NA_real_]
dcast.data.table(DD, f2 ~ i.f2, fun.aggregate = sum, value.var="pair_sum")
# f2 X Y Z
# 1: X NA 10 8
# 2: Y 10 NA 9
# 3: Z 8 9 NA
m<-subset(merge(D,D,"f1"),f2.x!=f2.y)
m<-aggregate(val.x~f2.x+f2.y,data=m,sum)
m<-xtabs(val.x~f2.x+f2.y, data=m)
m+t(m)
f2.x
f2.y X Y Z
X 0 10 8
Y 10 0 9
Z 8 9 0