计算列子集上的行均值

给出一个样本数据框架:

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保持一致。

195226 次浏览

从你的数据帧 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

计算列子集上的行平均值:

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

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

可以在数据框中创建一个新行,其中 $对应于 Means

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

使用 Dplyr:

library(dplyr)


DF %>%
transmute(ID,
Mean = rowMeans(across(C1:C3)))

或者

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

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

您应该尝试使用 pivot _ long 来获取从宽表单到长表单的数据,请阅读 pivot _ long & pivot _ wide (https://tidyr.tidyverse.org/articles/pivot.html)上的最新 tidyR 更新

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

rowMeans很好,但是如果您仍然试图了解 apply函数族,那么这是一个很好的机会来开始理解它。

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

注意,我所做的作业与第一个例子稍有不同。这种方法使得将其合并到 for 循环中变得更加容易。

改编自: 给你,适用于 N 组不同的列

library(dplyr, warn.conflicts = FALSE)
library(purrr)
row_means <- DF %>%
dplyr::select(where(is.numeric)) %>%
split.default(stringr::str_remove(names(df), '[0-9]')) %>%
map(rowMeans) %>%
setNames(paste0("mean_", names(.)))
DF %>%
mutate(
!!!row_means
)