R 按名称统计来自多行和多列的数据

R stats on data from multiple rows and columns by name

我有一个大型数据框,每个唯一 ID 对应 12 行。我想按 ID 计算 8 列值的平均值。换句话说,我想要一个 12x8 块中所有值的单一值均值(有些有很多 NA)

这是一个更简单的 3x4 块版本:

ht.1<-c(3,2,4,4,5,4)
ht.2<-c(3,7,3,4,1,2)
ht.3<-c(5,4,3,6,3,NA)
ht.4<-c(6,2,3,3,NA,4)
DF<-data.frame(ID=c("A","A","A","B","B","B"),ht.1=ht.1,ht.2=ht.2,ht.3=ht.3,ht.4=ht.4)

我正在寻找与 "A" 和 "B"

对应的所有值的平均值

聚合函数?

希望这是有道理的——我是这个网站和 R 的新手。

base R中的一个选项是

 vapply(split(DF[-1], DF$ID), function(x) mean(as.matrix(x), 
             na.rm=TRUE), numeric(1L))
 #   A    B 
 #3.75 3.60 

或者

 tapply(as.matrix(DF[-1]), DF$ID[row(DF[-1])], FUN=mean, na.rm=TRUE)
 #  A   B 
 #3.75 3.60 

 library(dplyr)
  DF %>%
     group_by(ID) %>%
     do(data.frame(val=mean(unlist(.[-1]), na.rm=TRUE)))
  #  ID  val
  #1  A 3.75
  #2  B 3.60

您可以只 unlist 相关值,然后汇总这些值。这是基本 R 中的一种方法:

by(DF[-1], DF[1], FUN = function(x) mean(unlist(x), na.rm = TRUE))
# ID: A
# [1] 3.75
# ------------------------------------------------------------------ 
# ID: B
# [1] 3.6

或者,您可以使用 stack 然后 aggregate:

aggregate(values ~ ID, cbind(DF[1], stack(DF[-1])), 
          function(x) mean(x, na.rm = TRUE))
#   ID values
# 1  A   3.75
# 2  B   3.60

"data.table" 方法特别紧凑和高效:

library(data.table)
as.data.table(DF)[, mean(unlist(.SD), na.rm = TRUE), by = ID]
#    ID   V1
# 1:  A 3.75
# 2:  B 3.60

这里有两段来自 Hadleyverse 的片段。

library(reshape2)
dcast(melt(DF, id.vars = "ID"), ID ~ "mean.ht", value.var = "value", 
      fun.aggregate = function(x) mean(x, na.rm = TRUE))
#   ID mean.ht
# 1  A    3.75
# 2  B    3.60

library(tidyr)
library(dplyr)
DF %>%
  gather(var, val, ht.1:ht.4) %>%
  group_by(ID) %>%
  summarise(val = mean(val, na.rm = TRUE))
# Source: local data frame [2 x 2]
# 
#   ID  val
# 1  A 3.75
# 2  B 3.60