【问题标题】:Find the 2 max values for each factor in R找到 R 中每个因子的 2 个最大值
【发布时间】:2014-08-08 23:38:43
【问题描述】:

我有一个关于为 A 列中的每个唯一 ID 查找 C 列的两个最大值,然后计算 B 列的平均值的问题。我的数据样本在这里:

ID  layer   weight
1   0.6843629   0.35
1   0.6360772   0.70
1   0.6392318   0.14
2   0.3848640   0.05
2   0.3882660   0.30
2   0.3877026   0.10
2   0.3964194   0.60
2   0.4273218   0.02
2   0.3869507   0.12
3   0.4748541   0.07
3   0.5853659   0.42
3   0.5383678   0.10
3   0.6060287   0.60
4   0.4859274   0.08
4   0.4720740   0.48
4   0.5126481   0.08
4   0.5280899   0.48
5   0.7492097   0.07
5   0.7220433   0.35
5   0.8750000   0.10
5   0.8302752   0.50
6   0.4306283   0.10
6   0.4890895   0.25
6   0.3790714   0.20
6   0.5139686   0.50
6   0.3885678   0.02
6   0.4706815   0.05

对于每个 ID,我想计算层的平均值,只使用两个权重最高的行。

我可以使用 R 中的以下代码来做到这一点:

ind.max1 <- ddply(index1, "ID", function(x) x[which.max(x$weight),]) 
    dt1 <- data.table(index1, key=c("layer"))
    dt2 <- data.table(ind.max1, key=c("layer"))
    index2 <- dt1[!dt2]
    ind.max2 <- ddply(index2, "ID", function(x) x[which.max(x$weight),])
ind.max.all <- merge(ind.max1, ind.max2, all=TRUE)
ind.ndvi.mean <- as.data.frame(tapply(ind.max.all$layer, list(ind.max.all$ID), mean))

这使用ddply 选择每个 ID 的第一个最高权重值并放入带有层的数据帧中。然后使用data.table 从原始数据帧中删除这些最高权重值。然后我重复ddply 选择最大值,并将两个最大权重值数据帧合并为一个。最后,用tapply 计算平均值。 必须有更有效的方法来做到这一点。有没有人有任何见解?干杯。

【问题讨论】:

标签: r dataset max subset


【解决方案1】:

你可以使用data.table

 library(data.table)
 setDT(dat)[, mean(layer[order(-weight)[1:2]]), by=ID]
 #   ID Meanlayer
 #1:  1 0.6602200
 #2:  2 0.3923427
 #3:  3 0.5956973
 #4:  4 0.5000819
 #5:  5 0.7761593
 #6:  6 0.5015291
  • 按降序排列weightorder(-weight)
  • [1:2]按组ID创建的订单中选择前两个
  • 根据索引layer[order..] 子集相应的layer
  • mean

或者,在1.9.3(当前开发版本)或从下一个版本开始,导出函数setorder,用于以任何顺序重新排序data.tables,通过引用

require(data.table) ## 1.9.3+
setorder(setDT(dat), ID, -weight) ## dat is now reordered as we require
dat[, mean(layer[1:min(.N, 2L)]), by=ID]

通过先排序,我们避免了对每个组的order() 调用(ID 中的唯一值)。这对于更多的组会更有利。而且setorder()order() 效率更高,因为它不需要创建数据副本。

【讨论】:

  • @Arun。感谢 1.9.3+ 解决方案。我想我需要安装新版本。
【解决方案2】:

这实际上是 StackOverflow 的问题......无论如何! 不知道下面的版本对你来说是否足够高效...

s.ind<-tapply(df$weight,df$ID,function(x) order(x,decreasing=T))
val<-tapply(df$layer,df$ID,function(x) x)

foo<-function(x,y) list(x[y][1:2])
lapply(mapply(foo,val,s.ind),mean)

【讨论】:

    【解决方案3】:

    我认为这可以做到。假设数据名为dat

    > sapply(split(dat, dat$ID), function(x) { 
          with(x, {
              mean(layer[ weight %in% rev(sort(weight))[1:2] ])
              })
          })
    #         1         2         3         4         5         6 
    # 0.6602200 0.3923427 0.5956973 0.5000819 0.7761593 0.5015291 
    

    您可能希望将na.rm = TRUE 作为mean 的第二个参数包含在内,以说明任何包含NA 值的行。

    或者,mapply 可能更快,并且具有完全相同的代码,只是顺序不同,

    mapply(function(x) { 
          with(x, {
              mean(layer[ weight %in% rev(sort(weight))[1:2] ])
              })
          }, split(dat, dat$ID))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-25
      • 1970-01-01
      • 2021-02-08
      • 2020-02-07
      • 1970-01-01
      • 2021-05-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多