R: совокупные столбцы data.frame

У меня есть 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"

Какова ослепляюще очевидная вещь, которую я пропускаю?

7
задан Mike Dewar 27 July 2010 в 22:26
поделиться

4 ответа

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

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

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

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

df$ID <- 1:nrow(df)

или, если эти имена имеют смысл

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 должен выглядеть как желаемый фрагмент вывода.

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

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

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

cast(df.m, .~variable, fun = mean)
8
ответ дан 6 December 2019 в 14:00
поделиться

А что насчет чего-то вроде

l <-lapply(unique(colnames(df)), function(x) rowMeans(df[,colnames(df) == x]))



df <- do.call(cbind.data.frame, l)
4
ответ дан 6 December 2019 в 14:00
поделиться

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

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

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

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

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

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

3
ответ дан 6 December 2019 в 14:00
поделиться

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

0
ответ дан 6 December 2019 в 14:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: