R 中各列的平均值,不包括 NA
Posted
技术标签:
【中文标题】R 中各列的平均值,不包括 NA【英文标题】:Average across Columns in R, excluding NAs 【发布时间】:2012-09-11 06:19:14 【问题描述】:我无法想象我是第一个提出这个问题的人,但我还没有找到解决方案(这里或其他地方)。
我有几列,我想在 R 中对其进行平均。唯一最棘手的方面是某些列包含 NA。
例如:
Trait Col1 Col2 Col3
DF 23 NA 23
DG 2 2 2
DH NA 9 9
我想创建一个 Col4 来平均前 3 列中的条目,忽略 NA。 所以:
Trait Col1 Col2 Col3 Col4
DF 23 NA 23 23
DG 2 2 2 2
DH NA 9 9 9
理想情况下这样的事情会起作用:
data$Col4 <- mean(data$Chr1, data$Chr2, data$Chr3, na.rm=TRUE)
但事实并非如此。
【问题讨论】:
?rowMeans
应该为你做。它主要是 apply(..., 1, mean)
的包装器。
不正确,它是 apply() 的包装器。众所周知,它的速度要快得多。
【参考方案1】:
你想要rowMeans()
,但重要的是要注意它有一个na.rm
参数,你想将其设置为TRUE
。例如:
> mat <- matrix(c(23,2,NA,NA,2,9,23,2,9), ncol = 3)
> mat
[,1] [,2] [,3]
[1,] 23 NA 23
[2,] 2 2 2
[3,] NA 9 9
> rowMeans(mat)
[1] NA 2 NA
> rowMeans(mat, na.rm = TRUE)
[1] 23 2 9
为了匹配你的例子:
> dat <- data.frame(Trait = c("DF","DG","DH"), mat)
> names(dat) <- c("Trait", paste0("Col", 1:3))
> dat
Trait Col1 Col2 Col3
1 DF 23 NA 23
2 DG 2 2 2
3 DH NA 9 9
> dat <- transform(dat, Col4 = rowMeans(dat[,-1], na.rm = TRUE))
> dat
Trait Col1 Col2 Col3 Col4
1 DF 23 NA 23 23
2 DG 2 2 2 2
3 DH NA 9 9 9
【讨论】:
行意思是!感谢您的宝贵时间:] 这是(正确但)不够通用,不值得记住。我添加了另一个答案。 @azim r 标签中有超过 300,000 个问题。其中不少人将apply()
和 co 作为潜在答案。问题是关于行均值;您不想经常使用apply()
这样做,因为相比之下它非常慢。您正在回答的问题在这里没有被问到,但在其他地方已经被问过很多次了。
@GavinSimpson 这个问题没有说明执行时间或数据集很大的事实。主要问题是如何在计算 mean
时摆脱 NA。此外,您始终可以翻转数据框并对列而不是行进行操作。此外,您可以并行运行,并且运行速度比任何“快速”但顺序操作都快。使用apply
函数系列非常容易。我对这个答案的主要问题是它的局限性。我认为对每个存在的函数都有一个行函数是不现实的。
@Azim 这个问题并没有说明做任何事情,而是在考虑NA
s 的同时将手段置于行之上。但这并没有阻止您来到这里并告诉人们正确的答案不“值得记住”。我关心执行时间,并且可以选择在您编写的代码中使用rowMeans()
和colMeans()
,尤其是如果它会被其他人使用。您可能认为拥有按行或按列的特殊功能并不重要,但其他人不同意; matrixStats 包,它专门添加了许多像这样可以轻松加速的常用函数【参考方案2】:
为什么不接受答案?
公认的答案是正确的,但是对于这个特定任务过于具体,无法一概而论。如果我们需要 var
、skewness
等其他统计信息,甚至是自定义函数,而不是 mean
,该怎么办?
更灵活的解决方案:
row_means <- apply(X=data, MARGIN=1, FUN=mean, na.rm=TRUE)
更多详情请关注apply
:
通常,要在整个数据集上应用任何函数(自定义或内置),按列或按行,apply
或其变体之一(sapply
,lapply`,...)应该使用。它的签名是:
apply(X, MARGIN, FUN, na.rm)
地点:
X
:表单数据框或矩阵的数据。
MARGIN
:聚合发生的维度。使用1
进行行操作,2
进行列操作。
FUN
:对数据调用的操作。这里可以使用任何预定义的 R 函数以及任何用户定义的函数。
na.rm
:如果是TRUE
,则NA
的值将在FUN
被调用之前被删除。
我为什么要使用apply
?
出于多种原因,包括但不限于:
-
任何功能都可以轻松插入
apply
。
对于不同的首选项,例如输入或输出数据类型,可以使用其他变体(例如,lapply
用于列表操作)。
(最重要的是)它促进了可扩展性,因为该函数的某些版本允许并行执行(例如来自parallel
库的mclapply
)。例如,请参阅 [+] 或 [+]。
【讨论】:
你没有提到你不应该使用apply()
来做OP想要的重要原因;很慢。以上是关于R 中各列的平均值,不包括 NA的主要内容,如果未能解决你的问题,请参考以下文章