通过另一个矩阵中的值聚合一个矩阵

时间:2014-01-30 19:17:14

标签: r matrix

正如我常常做的那样,我正在使用矩阵密切关注我的猫。

catWeights <- cbind(fluffy=c(5.0,5.1,5.2,5.3),misterCuddles=c(1.2,1.3,1.4,1.5),captainMew=c(4.3,4.2,4.1,4.0))
catTypes <- cbind(fluffy=c('cat','cat','cat','cat'),misterCuddles=c('kitten','kitten','kitten','cat'),captainMew=c('cat','cat','cat','cat'))
dates <- c("2013-01-01", "2013-01-02", "2013-01-03","2013-01-04")
row.names(catWeights) <- dates
row.names(catTypes) <- dates

在任何一个日期,我都知道他们每个人的权重:

> catWeights
           fluffy misterCuddles captainMew
2013-01-01    5.0           1.2        4.3
2013-01-02    5.1           1.3        4.2
2013-01-03    5.2           1.4        4.1
2013-01-04    5.3           1.5        4.0

我知道他们是猫还是小猫:

> catTypes
           fluffy misterCuddles captainMew
2013-01-01 "cat"  "kitten"      "cat"     
2013-01-02 "cat"  "kitten"      "cat"     
2013-01-03 "cat"  "kitten"      "cat"     
2013-01-04 "cat"  "cat"         "cat"  

我如何知道我的猫和所有小猫在一段时间内的重量?

我想要这个:

> totalWeights

             cat    kitten
2013-01-01   9.3       1.2
2013-01-02   9.3       1.3
2013-01-03   9.3       1.4
2013-01-04  10.8       0.0

1月4日,Cuddles先生1岁,所以他不再是小猫了。他的体重从小猫桶转移到猫桶。

3 个答案:

答案 0 :(得分:4)

使用示例数据似乎有效:

do.call(cbind, 
      lapply(c("cat", "kitten"), 
            function(x) rowSums(catWeights * (catTypes == x))))
#           [,1] [,2]
#2013-01-01  9.3  1.2
#2013-01-02  9.3  1.3
#2013-01-03  9.3  1.4
#2013-01-04 10.8  0.0

编辑:

@BlueMagister评论... lapply(unique(as.vector(catTypes)), ...是答案的更一般形式。我想,你已经找到了解决这个问题的方法,因为你接受了答案。 as.vector是因为unique具有matrix方法,在这种特定情况下不方便。

此外,由于我处于编辑模式,我会注意到sapply可能已被使用,但基于我不时做出的一些粗略基准,我发现{{}即使伴随着lapplydo.call(r/cbind, ..),也要快一些。但是,我没有在这个特定情况下测试更大的数据集。

所以,答案的另一种形式可能是:

unlist

答案 1 :(得分:0)

这是一个不太常见的答案,仅适用于示例数据集。

# Construct matrices for the cat weights and kitten weights
catWts <- ifelse(catTypes=="cat", catWeights[catTypes=="cat"], 0)
kittenWts <- ifelse(catTypes=="kitten", catWeights[catTypes=="kitten"], 0)

# Well, then just take the row sums for the two matrices
catSums <- rowSums(catWts)
kittenSums <- rowSums(kittenWts)

# Then combine it to a data frame
totalWeights <- data.frame(cat=catSums, kitten=kittenSums)

# In one line
data.frame(cat=rowSums(ifelse(catTypes=="cat", catWeights[catTypes=="cat"], 0)),
           kitten=rowSums(ifelse(catTypes=="kitten", catWeights[catTypes=="kitten"], 0)))

#            cat kitten
#2013-01-01  9.0    1.3
#2013-01-02 10.1    1.4
#2013-01-03 10.3    1.2
#2013-01-04 14.6    0.0

我认为有一种更通用的方法来解决这个问题。

答案 2 :(得分:0)

微生物标记alexis_laz在具有10组的2500x2500矩阵上的两个解决方案:

> microbenchmark(cbindLapply(), sapplyOnly(), times=100)
Unit: milliseconds
          expr      min       lq   median       uq      max neval
 cbindLapply() 841.4796 865.2220 879.9099 892.6265 990.5915   100
  sapplyOnly() 846.3675 869.7372 879.0286 901.3314 979.6136   100