2010-07-27 6 views
6

У меня есть data.frame, который выглядит, как этотR: агрегатные Столбцы data.frame

> head(df) 
      Memory Memory Memory Memory Memory  Naive  Naive 
10472501 6.075714 5.898929 6.644946 6.023901 6.332126 8.087944 7.520194 
10509163 6.168941 6.495393 5.951124 6.052527 6.404401 7.152890 8.335509 
10496091 10.125575 9.966211 10.075613 10.310952 10.090649 11.803949 11.274480 
10427035 6.644921 6.658567 6.569745 6.499243 6.990852 8.010784 7.798154 
10503695 8.379494 8.153917 8.246484 8.390747 8.346748 9.540236 9.091740 
10451763 10.986717 11.233819 10.643245 10.230697 10.541396 12.248487 11.823138 

, и я хотел бы найти среднее значение Memory колонка и среднее значение Naive столбцов. Функция aggregate объединяет строки. Это data.frame потенциально может иметь большое количество строк, и, следовательно, перенося затем применяя aggregate по colnames оригинального data.frame меня поражает, как плохо, и, как правило, раздражает:

> head(t(aggregate(t(df),list(colnames(df)), mean))) 
     [,1]  [,2]  
Group.1 "Memory" "Naive" 
10472501 "6.195123" "8.125439" 
10509163 "6.214477" "7.733625" 
10496091 "10.11380" "11.55348" 
10427035 "6.672665" "8.266854" 
10503695 "8.303478" "9.340436" 

Что стало очевидным, что я пропускаю ?

+1

увлечены глазами среди вы заметите, что 8,12 это не среднее 8.08 7.52: Есть несколько столбцов в действительности. Не так много, хотя! –

ответ

8

Я большой сторонник переформатирование данных таким образом, что это в формате «длинный». Полезность длинного формата особенно очевидна, когда дело касается таких проблем. К счастью, достаточно легко переформатировать данные, подобные этому, в любой формат с помощью пакета reshape.

Если я правильно понял ваш вопрос, вы хотите, чтобы среднее значение Memory и Naive для каждой строки. По какой-то причине нам нужно сделать имена столбцов уникальными для reshape::melt().

colnames(df) <- paste(colnames(df), 1:ncol(df), sep = "_") 

Тогда вам придется создать ID колонку. Вы можете либо сделать

df$ID <- 1:nrow(df) 

или, если эти rownames значимы

df$ID <- rownames(df) 

Теперь, с reshape пакет

library(reshape) 
df.m <- melt(df, id = "ID") 
df.m <- cbind(df.m, colsplit(df.m$variable, split = "_", names = c("Measure", "N"))) 
df.agg <- cast(df.m, ID ~ Measure, fun = mean) 

df.agg должен теперь выглядеть ваш желаемой выходной Snippit.

Или, если вам нужны только общие средства по всем строкам, предложение Зака ​​будет работать. Что-то вроде

m <- colMeans(df) 
tapply(m, colnames(df), mean) 

Вы можете получить тот же результат, но отформатированы как dataframe с

cast(df.m, .~variable, fun = mean) 
+0

Давать Джо тик, потому что это, кажется, правильный способ сделать что-то, поэтому очень спасибо! Но да, как говорит Джон, очевидная вещь, которую я отсутствовала, - это просто функция rowMeans, которую я еще не забуду! –

+0

Erm - быстрый вопрос. Любая идея, почему 's <- cast (df.m, ID ~ variable, fun = var)' возвращает мне кучу нулей, когда 'fun = mean', похоже, работает нормально, а также работает fun = sum? Дисперсия этих столбцов не равна нулю. –

+0

Хорошая добыча! Я не знаю, что такое сделка, но поскольку имена столбцов не были уникальными, они не расплавились правильно. Я отредактировал свой ответ, чтобы он теперь работал! – JoFrhwld

0

Я думаю, что вы загрузили свои данные без header=TRUE и что у вас есть фактор-матрица, и поэтому ваша вообще хорошая идея не срабатывает.

3

А что-то вроде

lapply(unique(colnames(df)), function(x) rowMeans(df[,colnames(df) == x])) 
+0

Спасибо, Джонатан! Это то, что говорила мне какая-то часть моего мозга, я просто не мог вспомнить. –

3

Чтобы уточнить ответ Джонатана Чанга ... слепо очевидно, что вам не хватает в том, что вы можете просто выберите столбцы и выполните команду rowMeans. Это даст вектор средств для каждой строки. Его команда получает значение строки для каждой группы уникальных имен столбцов и было именно тем, что я собирался написать. С вашими образцовыми данными результатом его команды является два списка.

rowMeans также очень быстро.

Чтобы разбить его, чтобы получить средства всех столбцов памяти только просто

rowMeans(df[,colnames(df) == 'Memory']) #or from you example, rowMeans(df[,1:5]) 

Это самый простой полный правильный ответ, голосовать его и пометить его правильно, если вам это нравится.

(Кстати, я также любил рекомендацию Джо, чтобы сохранить как правило, вещи, как длинные данные.)

0
m = matrix(1:12,3) 
colnames(m) = c(1,1,2,2) 

m 

    1 1 2 2 
[1,] 1 4 7 10 
[2,] 2 5 8 11 
[3,] 3 6 9 12 

mt = t(m) 
sapply(by(mt,rownames(mt),colMeans),identity) 

    1 2 
V1 2.5 8.5 
V2 3.5 9.5 
V3 4.5 10.5 
+0

Можете ли вы дать объяснение? –

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