我有一个包含2列的cvs文件(例如,参见下面的Matrix 1)。我想创建一个程序来平均第一列中所有重复数字的矩阵的第二列。因此,例如在下面的矩阵中,第一列中有两行“2”。这些行将被平均为((356 + 456)/ 2 = 406)等的一列。因此最终矩阵将喜欢底部的矩阵2。关于如何做到这一点的任何想法?
Matrix 1
mat1 <- structure(c(1, 2, 2, 3, 4, 4, 4, 5, 234, 356, 456, 745, 568,
998, 876, 895), .Dim = c(8L, 2L))
mat1
[,1] [,2]
[1,] 1 234
[2,] 2 356
[3,] 2 456
[4,] 3 745
[5,] 4 568
[6,] 4 998
[7,] 4 876
[8,] 5 895
Matrix 2
mat2 <- structure(c(1, 2, 3, 4, 5, 234, 406, 745, 814, 895), .Dim = c(5L, 2L))
mat2
[,1] [,2]
[1,] 1 234
[2,] 2 406
[3,] 3 745
[4,] 4 814
[5,] 5 895
答案 0 :(得分:2)
仅使用基础R:
> x <- tapply(mat1[,2], mat1[,1], mean)
> matrix(c(as.integer(names(x)), x), ncol = 2)
答案 1 :(得分:1)
最基本的方法是使用tapply
:
tapply(mat1[,2], mat1[,1], mean)
答案 2 :(得分:1)
怎么样?
as.matrix(aggregate(mat1[,2],by = list(mat1[,1]),FUN = mean))
答案 3 :(得分:1)
如果第一列始终按数字顺序排列,则可以尝试
cbind(unique(mat1[,1]), rowsum(mat1[,2], mat1[,1]) %/% matrix(table(mat1[,1])))
# [,1] [,2]
# [1,] 1 234
# [2,] 2 406
# [3,] 3 745
# [4,] 4 814
# [5,] 5 895
众所周知, rowsum
比aggregate
和tapply
更有效率。但是,存在明显的局限性。如果有一个rowmean
函数用于分组矩阵计算,那就太好了。
另一个基础R可能性是
s <- unname(split(mat1[,2], mat1[,1]))
cbind(unique(mat1[,1]), vapply(s, mean, 1))
# [,1] [,2]
# [1,] 1 234
# [2,] 2 406
# [3,] 3 745
# [4,] 4 814
# [5,] 5 895
这三者的更安全的解决方案是转换为数据框架。在这里,我使用dplyr
来提高效率。
library(dplyr)
df <- group_by(as.data.frame(mat1), V1) %>% summarise(mean(V2))
as.matrix(unname(df))
# [,1] [,2]
# [1,] 1 234
# [2,] 2 406
# [3,] 3 745
# [4,] 4 814
# [5,] 5 895
答案 4 :(得分:1)
@LeoRJorge的答案是所需输出的98%,只需要取消命名(如果真的需要):
unname(as.matrix(aggregate(mat1[,2], list(mat1[,1]), mean)))
[,1] [,2]
[1,] 1 234
[2,] 2 406
[3,] 3 745
[4,] 4 814
[5,] 5 895