返回具有多个条件的向量中的最高值

时间:2015-08-07 15:21:22

标签: r dplyr summary

我有这些示例数据

Data <- structure(list(IndID = structure(c(1L, 1L, 2L, 2L, 3L, 3L, 4L, 
4L, 5L, 5L, 6L, 6L, 7L, 7L, 8L, 8L, 9L, 9L, 10L, 10L), .Label = c("1", 
"2", "3", "4", "5", "56", "58", "59", "60", "63"), class = "factor"), 
    Species = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("BHS", 
    "MTG"), class = "factor"), Season = structure(c(1L, 2L, 1L, 
    2L, 2L, 1L, 1L, 2L, 2L, 1L, 2L, 1L, 1L, 2L, 1L, 2L, 1L, 2L, 
    1L, 2L), .Label = c("Summer", "Winter"), class = "factor"), 
    Percent = c(0.992, 0.992, 0.996, 0.976, 0.995, 0.871, 0.996, 
    0.996, 0.916, 0.875, 0.652, 0.802, 0.964, 0.673, 0.956, 0.879, 
    0.972, 0.782, 0.968, 0.832)), .Names = c("IndID", "Species", 
"Season", "Percent"), row.names = c(NA, -20L), class = "data.frame")

看起来像这样

> head(Data)
  IndID Species Season Percent
1     1     BHS Summer   0.992
2     1     BHS Winter   0.992
3     2     BHS Summer   0.996
4     2     BHS Winter   0.976
5     3     BHS Winter   0.995
6     3     BHS Summer   0.871

有10个独特个体属于两个物种之一(BHS或MTG)。对于每个人(IndID),每个季节(冬季和夏季)都有一个百分比值。

对于每个物种,我想选择平均百分比值最高的两个人。

编辑另见下面的注释。我没有发布具体的结果,因为有多个可以满足我的需求。因为我需要每个季节的百分比,我认为取百分比的平均值将是选择顶级个体的最佳方法。每个季节测量的百分比,但我想选择最高级别的IndID。我也可以用百分比(而不是平均值)的总和来对IndID进行排名。

除了@akrun发布的第二个代码块之外,4个IndIDs的矢量(每个物种排名最高的两个)也将是一个很好的输出。

提前感谢您的帮助。

4 个答案:

答案 0 :(得分:8)

假设您想要一个dplyr解决方案(来自代码),我们会按“种类”对数据进行分组,按降序排序“百分比”列(arrange)并使用{{1}获取每个'Species'的前两行

slice

预期的输出会更容易。如果这是基于平均百分比,我们按'物种'和'IndID'分组,根据'{1}}'百分比'创建一个新列'AvgPercent',我们按'物种'分组,订购'AvgPercent' '列按降序排列并获得前两个'IndID'

library(dplyr)
Data %>%
      group_by(Species) %>%
      arrange(desc(Percent)) %>%
      slice(1:2)
#    IndID Species Season Percent
#1     2     BHS Summer   0.996
#2     4     BHS Summer   0.996
#3    60     MTG Summer   0.972
#4    63     MTG Summer   0.968

答案 1 :(得分:3)

使用tidyr的{​​{1}}和gather

的其他选项
spread

这是library(dplyr) library(tidyr) Data %>% spread(Season, Percent) %>% mutate(avg = (Summer + Winter)/2) %>% group_by(Species) %>% arrange(desc(avg)) %>% top_n(2) # IndID Species Summer Winter avg #1 4 BHS 0.996 0.996 0.9960 #2 1 BHS 0.992 0.992 0.9920 #3 59 MTG 0.956 0.879 0.9175 #4 63 MTG 0.968 0.832 0.9000 方法

data.table

答案 2 :(得分:2)

plyr

 ddply(Data, "Species", function(x) sort(x[, "Percent"], T))[, 1:3]
  Species    V1    V2
1     BHS 0.996 0.996
2     MTG 0.972 0.968

答案 3 :(得分:2)

data.table解决方案(library(data.table))。

d <- data.table(Data)将您的Data包裹到data.table个对象中。

制作一张新表格,其中还列出了每个人的平均百分比(夏季和冬季之间)。

t <- d[, meanPercent := mean(Percent), by = IndID]

根据IndID

合并某些行

t <- t[, .SD[, list(Species, meanPercent)][1], by = IndID]

最后按每个物种的平均百分比选择前两个人。

t[order(-meanPercent)][Species == "BHS"][1:2]

t[order(-meanPercent)][Species == "MTG"][1:2]