R函数计算最高值的平均值/中值

时间:2014-07-19 17:20:06

标签: r function

我有一个包含2列的数据框,其中一列带有数字值,另一列带有名称。名称重复,但每次都有不同的值。

Data <- data.frame(
Value = c(1:10),
Name = rep(LETTERS, each=4)[1:10])

我想编写一个函数,它为每个名称取3个最高数字并计算平均值和中位数(如果没有3个值存在则抛出NA)然后获取每个名称的所有值并计算平均值和中位数。 我最初的尝试看起来像这样:

my.mean <- function (x,y){
  top3.x  <- ifelse(x > 3 , NA, x)
  return(mean(top3.x), median(top3.x))
}

任何关于如何改进这一点的提示都将受到赞赏。

3 个答案:

答案 0 :(得分:2)

我可能会为此推荐by

快速拼凑的东西可能看起来像这样(如果我理解你的问题):

myFun <- function(indf) {
  do.call(rbind, with(indf, by(Value, Name, FUN=function(x) {
    Vals <- head(sort(x, decreasing=TRUE), 3)
    if (length(Vals) < 3) {
      c(Mean = NA, Median = NA)
    } else {
      c(Mean = mean(Vals), Median = median(Vals))
    }
  })))
}
myFun(Data)
#   Mean Median
# A    3      3
# B    7      7
# C   NA     NA

请注意,由于有多少参数被硬编码到函数中,因此它在此形式中不是一个非常有用的函数。只有当您的数据采用您共享的形式时,它才真正有用。

答案 1 :(得分:1)

这是一个data.table解决方案,假设您的数据中没有任何其他NA:

require(data.table)  ## 1.9.2+
setDT(Data)          ## convert to data.table
Data[order(Name, -Value)][, list(m1=mean(Value[1:3]), m2=median(Value[1:3])), by=Name]

#    Name m1 m2
# 1:    A  3  3
# 2:    B  7  7
# 3:    C NA NA

答案 2 :(得分:0)

使用dplyr

 library(dplyr)
 myFun1 <- function(dat){
 dat %>%
 group_by(Name)%>%
 arrange(desc(Value))%>%
 mutate(n=n(), Value=ifelse(n<=3, NA_integer_, Value))%>%
 summarize(Mean=mean(head(Value,3)), Median=median(head(Value,3)))
 }

  myFun1(Data)
 #Source: local data frame [3 x 3]

 # Name Mean Median
 #1    A    3      3
 #2    B    7      7
 #3    C   NA     NA