2014-01-30 207 views
1

正如我所愿意做的那样,我使用矩阵来标记我的猫。按另一个矩阵中的值聚合一个矩阵

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,所以他不再是小猫。他的体重从小猫桶移到猫桶。

+0

可能在未来更好地存储你的数据在长格式,[喜欢在这个问题上(http://stackoverflow.com/问题/ 2185252 /重塑 - 数据 - 帧从全到长格式)。 –

回答

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可能已被使用,但基于我不时做出的一些粗略基准,我发现lapply甚至更​​快如果它伴随着do.call(r/cbind, ..)unlist。不过,我没有在这个特定的情况下测试一个更大的数据集。

,则回答的另一种格式可以一直:

sapply(unique(as.vector(catTypes)), 
      function(x) rowSums(catWeights * (catTypes == x))) 
+1

+1。更一般化:'独特(catTypes)'而不是'c(“猫”,“小猫”)'。然后将矩阵的列名设置为'unique(catTypes)'。 –

+0

在具有10个猫品种的2500x2500矩阵中,'microbenchmark'指示两种方法在速度上相似。我将在下面发布结果作为答案。谢谢! – dvmlls

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 

我会想象有一个更一般的方法来解决这个问题。

+0

我需要一个更一般的解决方案,因为我也跟踪很老的猫,幼猫和其他变老的小山狮。 – dvmlls

0

Microbenchmarking alexis_laz对一个2500x2500矩阵两种解决方案与10组:

> 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 
+0

有趣。感谢您分享您的实际数据信息! –

+0

我有这么多的F'ing猫。 – dvmlls

+0

我只有一个。这就是为什么我无法正确推断基准。.. :) –

相关问题