计算列子集上的行均值

Posted

技术标签:

【中文标题】计算列子集上的行均值【英文标题】:Calculate row means on subset of columns 【发布时间】:2012-06-12 07:51:33 【问题描述】:

给定一个示例数据框:

C1<-c(3,2,4,4,5)
C2<-c(3,7,3,4,5)
C3<-c(5,4,3,6,3)
DF<-data.frame(ID=c("A","B","C","D","E"),C1=C1,C2=C2,C3=C3)

DF
    ID C1 C2 C3
  1  A  3  3  5
  2  B  2  7  4
  3  C  4  3  3
  4  D  4  4  6
  5  E  5  5  3

创建包含ID 列和每行平均值的第二个数据框的最佳方法是什么?像这样的:

ID  Mean
A    3.66
B    4.33
C    3.33
D    4.66
E    4.33

类似于:

RM<-rowMeans(DF[,2:4])

我想让手段与他们的ID 保持一致。

【问题讨论】:

【参考方案1】:

计算列子集上的行均值:

创建一个新的 data.frame,它将 DF 的第一列指定为称为 ID 的列,并计算该行上所有其他字段的平均值,并将其放入标题为“平均值”的列中:

data.frame(ID=DF[,1], Means=rowMeans(DF[,-1]))
  ID    Means
1  A 3.666667
2  B 4.333333
3  C 3.333333
4  D 4.666667
5  E 4.333333

【讨论】:

【参考方案2】:

从您的数据框DF 开始,您可以使用data.table 包:

library(data.table)

## EDIT: As suggested by @MichaelChirico, setDT converts a
## data.frame to a data.table by reference and is preferred
## if you don't mind losing the data.frame
setDT(DF)

# EDIT: To get the column name 'Mean':

DF[, .(Mean = rowMeans(.SD)), by = ID]

#      ID     Mean
# [1,]  A 3.666667
# [2,]  B 4.333333
# [3,]  C 3.333333
# [4,]  D 4.666667
# [5,]  E 4.333333

【讨论】:

谢谢。还要注意class(DF),您不会丢失data.frame,因为任何寻找data.frame 对象的函数都应该在setDT 之后接受DF(尤其是现在data.table是成熟的一面) 如果我只想要 C2 和 C3 之间的行均值怎么办? 那么你可以使用DF[, .(Mean = rowMeans(.SD)), by = ID, .SDcols = c("C2", "C3")]。参数.SDcols 确定要包含在.SD 中的列。 @user3841581 @BenBarnes 就我而言,我不确定我想要采用 rowMeans 的实际列数,在某些情况下它们可能是 196,而在其他情况下可能是 198,依此类推。但是一个很常见的是他们名字的首字母,就像 Mgw.1, Mgw.2 ... Mgw.196 类似 Hel.1, Hel.2 ... Hel.198 所以我想做的是不要触摸 data.table 的初始 5 列,然后是所有具有首字母 Mgw 的列,获取它们的 rowMeans 并将其分配给 MGW(删除所有单独的列,只保留一个具有平均值的列),以此类推其余列。你能指导我怎么做吗? @Newbie 这听起来像是一个新问题,您应该自己发布。【参考方案3】:

您可以在与 Means 对应的数据框中使用$ 创建一个新行

DF$Mean <- rowMeans(DF[,2:4])

【讨论】:

【参考方案4】:

使用dplyr

library(dplyr)

# exclude ID column then get mean
DF %>%
  transmute(ID,
            Mean = rowMeans(select(., -ID)))

或者

# select the columns to include in mean
DF %>%
  transmute(ID,
            Mean = rowMeans(select(., C1:C3)))

#   ID     Mean
# 1  A 3.666667
# 2  B 4.333333
# 3  C 3.333333
# 4  D 4.666667
# 5  E 4.333333

【讨论】:

【参考方案5】:

(从最新的Tidyr 更新中使用pivot_longerpivot_wider 的另一种解决方案)

您应该尝试使用 pivot_longer 将数据从宽格式变为长格式 阅读有关 pivot_longer 和 pivot_wider 的最新 tidyR 更新 (https://tidyr.tidyverse.org/articles/pivot.html)

library(tidyverse)
C1<-c(3,2,4,4,5)
C2<-c(3,7,3,4,5)
C3<-c(5,4,3,6,3)
DF<-data.frame(ID=c("A","B","C","D","E"),C1=C1,C2=C2,C3=C3)

在这里输出

  ID     mean
  <fct> <dbl>
1 A      3.67
2 B      4.33
3 C      3.33
4 D      4.67
5 E      4.33

【讨论】:

【参考方案6】:

rowMeans 很好,但如果您仍然想了解apply 系列函数,这是开始理解它的好机会。

DF['Mean'] <- apply(DF[,2:4], 1, mean)

请注意,我正在做的作业与第一个示例略有不同。这种方法更容易将其合并到 for 循环中。

【讨论】:

以上是关于计算列子集上的行均值的主要内容,如果未能解决你的问题,请参考以下文章

如何按名称选择列的子集来计算 R 中的行均值? [复制]

数字数据集上的K-均值聚类

行子集上的 SQL AVG

大型数据集上的 R 中的 hclust()

什么是对不相交集上的行进行聚类的正确 JavaRDD 转换

从数据子集计算平均值和方差的在线算法