【问题标题】:Compute matrix of sums计算和矩阵
【发布时间】:2014-09-30 23:25:07
【问题描述】:

假设我有一个包含几列分类数据和一列定量数据的 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 的交叉表/总和的最优雅方法是什么,其中两个值都是=='t'?也就是说,我正在寻找这样的输出:

   A   B   C   D  
A "?" "?" "?" "?"
B "?" "?" "?" "?"
C "?" "?" "?" "?"
D "?" "?" "?" "?"

..x/y 的交集是quantity 的和,其中x=='t'y=='t'。 (我只关心这张表的一半,真的,因为一半是重复的)

所以例如 A/C 的值应该是:

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'])
  })
})

这给出了预期的结果:

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

我喜欢这个解决方案,因为它非常“字面意思”,可读性很强:两个应用函数(又名循环)遍历行 * 列,计算每个单元格并生成矩阵。我的实际数据也足够快(很小:192 行 x 10 列)。我不喜欢它,因为它看起来像很多行。感谢您到目前为止的答案!我会回顾和吸收。

【问题讨论】:

  • 既然您要求的是“优雅”的方式而不是“任何”的方式,您介意发布您现在所拥有的吗?这样我们就不会重写你已经编写的代码。
  • 好点,编辑显示我已经拥有的东西

标签: r data.table reshape2


【解决方案1】:

尝试使用矩阵乘法

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

(虽然这可能是侥幸)

【讨论】:

  • 美女!谢谢。这是一种让它在页面上更精简的方法:tf &lt;- my_data[, 1:4]=='t'; t(tf*my_data$quantity) %*% tf
【解决方案2】:

对于每个行名称,您可以构建一个向量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

【讨论】:

  • 谢谢!与我想到的有点相似的方法(第 1 步是行选择),但你的方法避免了第二个 sapply。赞成。
猜你喜欢
  • 2013-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-25
  • 1970-01-01
  • 2015-05-17
相关资源
最近更新 更多