我有一个数据框,包含10299个66个变量的观测值。其中一些变量共享一个共同的列名,我想计算每个观察变量的平均值。
具有以下矩阵,列名为c(A, B, C, B, A ,C)
:
A B C B A C
1 2 3 4 5 6
3 5 6 7 4 3
3 3 3 3 5 5
2 2 2 2 2 2
我想得到:
A B C
3 3 4.5
3.5 6 4.5
4 3 4
2 2 2
我尝试了循环,命令aggregate()
,但我没有得到所需的结果。
很抱歉,如果这个问题看起来太基础了,我已经检查了谷歌的可能解决方案,但我没有找到。
答案 0 :(得分:6)
这是一个解决方案。
首先让我们定义一个示例性data.frame(与您的示例中相同)。
df <- as.data.frame(
matrix(c(1,3,3,2,2,5,3,2,3,6,3,2,4,7,3,2,5,4,5,2,6,3,5,2),
ncol=6,
dimnames=list(NULL, c("A", "B", "C", "B", "A", "C"))
)
)
下面我们在每个唯一列名col
上应用自定义函数:
它会选择名为col
的所有列并计算rowMeans
。结果,原子矢量列表将被强制转换为data.frame:
res <- as.data.frame( # sapply returns a list here, so we convert it to a data.frame
sapply(unique(names(df)), # for each unique column name
function(col) rowMeans(df[names(df) == col]) # calculate row means
)
)
结果:
res
## A B C
## 1 3.0 3 4.5
## 2 3.5 6 4.5
## 3 4.0 3 4.0
## 4 2.0 2 2.0
修改强> 由于已经提出了许多解决方案,让我们对它们进行基准测试:
set.seed(123)
df <- as.data.frame(matrix(sample(1:9, replace=TRUE, 10000*100),
dimnames=list(NULL, sample(LETTERS[1:5], 100, replace=TRUE)), ncol=100))
library(microbenchmark)
microbenchmark(...)
## Unit: milliseconds
## min lq median uq max neval
## @gagolews 61.196075 65.73211 77.22533 119.42028 127.32557 10
## @joran 8.297964 10.05242 10.90564 15.25943 65.69156 10
## @Davide 5535.272680 5731.24220 5754.67006 5808.47807 5862.22628 10
明显的赢家(至少就速度而言)是@joran&#39; lapply
+ split
+ Reduce
。恭喜! : - )
答案 1 :(得分:5)
在我看来,这有效但不如gegolews解决方案好:
x <- read.table(text = "A B C B A C
1 2 3 4 5 6
3 5 6 7 4 3
3 3 3 3 5 5
2 2 2 2 2 2",header = TRUE,sep = "",check.names = FALSE)
as.data.frame(lapply(split(as.list(x),f = colnames(x)),function(x) Reduce(`+`,x) / length(x)))
## A B C
##1 3.0 3 4.5
##2 3.5 6 4.5
##3 4.0 3 4.0
##4 2.0 2 2.0
答案 2 :(得分:5)
使用apply
和tapply
的组合:
t(apply(df, 1, function(x) tapply(x, colnames(df), mean)))
# A B C
# [1,] 3.0 3 4.5
# [2,] 3.5 6 4.5
# [3,] 4.0 3 4.0
# [4,] 2.0 2 2.0
答案 3 :(得分:1)
您可以使用rowMeans
将数据框划分为基于列名的不同组,然后使用sapply(split.default(df, names(df)), rowMeans)
# A B C
#[1,] 3.0 3 4.5
#[2,] 3.5 6 4.5
#[3,] 4.0 3 4.0
#[4,] 2.0 2 2.0
获取具有相同名称的列的平均值。
df = structure(list(A = c(1L, 3L, 3L, 2L), B = c(2L, 5L, 3L, 2L),
C = c(3L, 6L, 3L, 2L), B = c(4L, 7L, 3L, 2L), A = c(5L, 4L,
5L, 2L), C = c(6L, 3L, 5L, 2L)), .Names = c("A", "B", "C",
"B", "A", "C"), class = "data.frame", row.names = c(NA, -4L))
数据强>
bucketSize