Нерасщепленная уменьшенная таблица данных на основе двух факторов в R

#r #split #dataframe #lapply #split-apply-combine

#r #сплит #фрейм данных #лапчатый #разделить-применить-объединить

Вопрос:

Предположим, у меня есть фрейм данных в R, где я хотел бы использовать 2 столбца «factor1» и «factor2» в качестве факторов, и мне нужно вычислить среднее значение для всех остальных столбцов для каждой пары вышеупомянутых факторов. После выполнения приведенного ниже кода в последней строке отображаются следующие предупреждения:

 Warning messages:
1: In split.default(seq_along(x), f, drop = drop, ...) :
  data length is not a multiple of split variable
 

Почему это происходит и что я должен сделать, чтобы все исправить? Спасибо.

Вот мой код:

 # Create data frame
myDataFrame <- data.frame(factor1=c(1,1,1,2,2,2,3,3,3), factor2=c(3,3,3,4,4,4,5,5,5), val1=c(1,2,3,4,5,6,7,8,9), val2=c(9,8,7,6,5,4,3,2,1))  

# Split by 2 columns (factors)
splitDataFrame <- split(myDataFrame, list(myDataFrame$factor1, mydataFrame$factor2))

# Calculate mean value for each column per each pair of factors
splitMeanValues <- lapply(splitDataFrame, function(x) apply(x, 2, mean))

# Combine back to reduced table whereas there is only one value (mean) per each pair of factors
MeanValues <- unsplit(splitMeanValues, list(unique(myDataFrame$factor1), unique(mydataFrame$factor2)))
 

EDIT1: Добавлено создание фрейма данных (см. Выше)

Комментарии:

1. Пожалуйста, предоставьте некоторые примеры данных, чтобы мы могли воспроизвести проблему.

2. @Richard Scriven: Спасибо, только что добавил строку, которая создает фрейм данных, см. Выше в вопросе.

Ответ №1:

Если вам нужно вычислить среднее значение для всех других столбцов, кроме факторов, вы можете использовать синтаксис формулы aggregate()

 aggregate(.~factor1 factor2, myDataFrame, FUN=mean)
 

Это возвращает

   factor1 factor2 val1 val2
1       1       3    2    8
2       2       4    5    5
3       3       5    8    2
 

Ваш split() метод не сработал, потому что при unsplit разделении данных у вас должно быть столько же строк, сколько и при разделении данных. Вы уменьшали количество строк для всех групп до одной строки. Кроме того, unsplit действительно следует использовать с тем же списком факторов, который использовался для выполнения split , иначе группы могут выйти из строя. Вы могли бы использовать a split , а затем lapply некоторую функцию свертывания, а затем rbind список обратно в один data.frame, если вы действительно хотели, но для простого среднего, aggregate вероятно, лучше.

Комментарии:

1. Спасибо, ваш метод сработал! Один вопрос, однако, когда я пробовал нерасщепленную, я использовал уникальную функцию в списке, поэтому векторы факторов также должны были быть уменьшены. Почему это не сработало?

2. Основная проблема заключается в том, что ваш splitMeanValues — это не список data.frames, это список именованных векторов. apply Функция плохо работает с data.frames, она преобразует входные данные в матрицу и, в конечном счете, в вектор благодаря вашей функции сокращения.

Ответ №2:

Тот же результат может быть получен с summaryBy() помощью in the doBy package. Хотя это почти то же aggregate() самое, что и в этом случае.

 > library(doBy)
> summaryBy( . ~ factor1 factor2, data = myDataFrame)
#   factor1 factor2 val1.mean val2.mean
# 1       1       3         2         8
# 2       2       4         5         5
# 3       3       5         8         2
 

Ответ №3:

Вы пробовали aggregate ?

aggregate(myDataFrame$valueColum, myDataFrame$factor1, FUN=mean)
aggregate(myDataFrame$valueColum, myDataFrame$factor2, FUN=mean)

Комментарии:

1. Попробовал: средние значения <- aggregate(myDataFrame, by=list(myDataFrame $factor1, mydataFrame $ factor2), FUN=mean), получил ошибку: аргументы должны иметь одинаковую длину. Все еще ошибка.