计算总和矩阵

时间:2014-09-30 23:25:08

标签: r data.table reshape2

假设我有一个包含多列分类数据的data.frame和一列定量数据。这是一个例子:

my_data <- structure(list(A = c("f", "f", "f", "f", "t", "t", "t", "t"), 
                          B = c("t", "t", "t", "t", "f", "f", "f", "f"), 
                          C = c("f","f", "t", "t", "f", "f", "t", "t"), 
                          D = c("f", "t", "f", "t", "f", "t", "f", "t")),
                     .Names = c("A", "B", "C", "D"), 
                     row.names = 1:8, class = "data.frame")
my_data$quantity <- 1:8

现在my_data看起来像这样:

  A B C D quantity
1 f t f f        1
2 f t f t        2
3 f t t f        3
4 f t t t        4
5 t f f f        5
6 t f f t        6
7 t f t f        7
8 t f t t        8

获取两个值quantity的{​​{1}}的交叉表/总和的最优雅方法是什么?也就是说,我正在寻找这样的输出:

=='t'

..其中x / y的交点是 A B C D A "?" "?" "?" "?" B "?" "?" "?" "?" C "?" "?" "?" "?" D "?" "?" "?" "?" quantityx=='t'之和的总和。 (我只关心这张桌子的一半,真的,因为有一半是重复的)

例如,A / C的值应为:

y=='t'

*编辑:我已经拥有的是:

good_rows <- with(my_data, A=='t' & C=='t')
sum(my_data$quantity[good_rows])

15

这给出了期望的结果:

nodes <- names(my_data)[-ncol(my_data)]
sapply(nodes, function(rw) {
  sapply(nodes, function(cl) {
    good_rows <- which(my_data[, rw]=='t' & my_data[, cl]=='t')
    sum(my_data[good_rows, 'quantity'])
  })
})

我喜欢这个解决方案,因为它非常'文字',它具有相当的可读性:两个应用funcs(aka循环)来遍历行*列,计算每个单元格,并生成矩阵。在我的实际数据上也足够快(微小:192行×10列)。我不喜欢它,因为它似乎很多线条。谢谢你到目前为止的答案!我会回顾并吸收。

2 个答案:

答案 0 :(得分:6)

尝试使用矩阵乘法

temp <- (my_data[1:4]=="t")*my_data$quantity

t(temp) %*% (my_data[1:4]=="t") 

#   A  B  C  D
#A 26  0 15 14
#B  0 10  7  6
#C 15  7 22 12
#D 14  6 12 20

(虽然这可能是侥幸)

答案 1 :(得分:3)

对于每个行名称,您可以构建一个向量dat,该向量只包含该值等于t的行。然后,您可以将此数据子集中的真/假值乘以该行的数量值(因此,当假为时它为0,当为真时为数量值),最后取列总和。

sapply(c("A", "B", "C", "D"), function(x) {
  dat <- my_data[my_data[,x] == "t",]
  colSums((dat[,-5] == "t") * dat[,5])
})
#    A  B  C  D
# A 26  0 15 14
# B  0 10  7  6
# C 15  7 22 12
# D 14  6 12 20