2014-11-24 4 views
3

У меня есть файл cvs с 2 столбцами (см. Ниже, например, Matrix 1). Я хотел бы создать программу, чтобы усреднить второй столбец матрицы для всех дубликатов чисел в первом столбце. Так, например, в приведенной ниже матрице в первом столбце есть две строки «2». Эти строки будут усреднены в один столбец ((356 + 456)/2 = 406) и т. Д. Таким образом, финальная матрица должна была бы иметь матрицу 2 внизу. Есть идеи, как это сделать?Матрица Усреднение повторяющихся строк

Матрица 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 

Матрица 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

ли первый столбец всегда в порядке? –

ответ

1

насчет

as.matrix(aggregate(mat1[,2],by = list(mat1[,1]),FUN = mean)) 
+0

Это не вернет матрицу –

+0

@David 'as.matrix (aggregate (mat1, by = list (mat1 [, 1]), FUN = mean)) ' – LeoRJorge

+0

И если вам не нужен столбец, созданный агрегированием' as.matrix (aggregate (mat1, by = list (mat1 [, 1]), FUN = mean)) [, - 1] ' – LeoRJorge

1

Самым элементарным способом было бы использовать tapply:

tapply(mat1[,2], mat1[,1], mean) 
+0

Это не вернет матрицу ни –

+2

@DavidArenburg True. Я не уверен, что OP лучше всего использовать матрицу - мое впечатление было то, что это был только первый тип данных, который, как он знал, мог хранить то, что ему нужно. По моему опыту, матрица во многих случаях не является лучшим типом данных для использования. Таким образом, я специально дал альтернативу. Я собирался прокомментировать это, но потом зазвонил мой телефон, и я отвлекся ... – Thilo

+0

@DavidArenburg, вы пишете эти комментарии так, как будто 'as.matrix' является неясной и трудно применимой функцией. – A5C1D2H2I1M1N2O1R2T1

2

используя только основание R:

> x <- tapply(mat1[,2], mat1[,1], mean) 
> matrix(c(as.integer(names(x)), x), ncol = 2) 
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 
+0

Спасибо, преобразование в фрейм данных также очень хорошо работает – CPL

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 
+1

Итак, вместо публикации ответа на 2% просто предложите отредактировать ответ, который доставит вам 98% пути .... – A5C1D2H2I1M1N2O1R2T1

+1

К сожалению, у меня пока нет достаточной репутации, чтобы оставлять комментарии (за исключением здесь, на моих собственных ответах), иначе я бы это сделал. Не стесняйтесь найти некоторые мои ответы, которые считаете полезными, и проголосуйте за них, если хотите. Благодарю. – goangit

+0

Интересно, в каком контексте имена будут нежелательными. Но если это так, то неудобство должно работать без проблем. – LeoRJorge

Смежные вопросы