Здесь есть пара вещей:
совет: никогда не используйте apply
с data.frame
(если только вы не абсолютно уверены, что не возражаете против затрат на преобразование в matrix
^ 1 и можете принять потенциальную потерю данных ^ 2).
даже если вы собираетесь использовать apply
, вы делаете это немного «выключено»: когда вы говорите apply(df, 2, func)
, он берет первый столбец df
и представляет его как аргументы, например,
apply(mtcars, 2, mean)
будет звонить как
mean(c(21, 21, 22.8, 21.4, 18.7, ...)) # mpg
mean(c(6, 6, 4, 6, 8, ...)) # cyl
mean(c(160, 160, 108, 258, 360, ...)) # disp
# ... etc
В этом контексте вы используете apply(inc_df, 2, function(x) GroupedMedian(inc_df[, x], ...))
неправильно, поскольку x
заменяется всеми значениями первого столбца inc_df
(а затем всеми значениями 2-го столбца и т. Д.).
Поскольку ваша функция выглядит так, как будто она принимает вектор значений (плюс некоторые другие аргументы), я предлагаю вам попробовать что-то вроде
inc_df[] <- lapply(inc_df, GroupedMedian, rownames(inc_df), sep="-", trim="cut")
Если вы хотите применить эту функцию к подмножеству этих столбцов, то что-то вроде этого работает хорошо:
ind <- c(1,3,7)
inc_df[ind] <- lapply(inc_df[ind], GroupedMedian, rownames(inc_df), sep="-", trim="cut")
Использование inc_df[] <- ...
(когда не выполняется подмножество столбцов) гарантирует, что мы заменим значения столбцов, не теряя атрибута, который является data.frame
. Фактически это то же самое, что и inc_df <- as.data.frame(...)
с некоторыми другими незначительными нюансами.
Примечания:
^ 1: apply
всегда преобразует data.frame
в matrix
. Это может быть хорошо, но с большими данными займет ненулевое количество времени. Это также может иметь последствия, см. Далее ...
^ 2: matrix
может иметь только один класс, в отличие от data.frame
. Это означает, что все столбцы будут преобразованы с повышением до общего общего типа, порядка logical < integer < numeric < POSIXct < character
. Это означает, что если у вас есть все numeric
столбцы и один character
, то функция, которую вы apply
используете, будет видеть все character
данные. Этого можно избежать, выбрав только те столбцы с ожидаемыми вами типами, например:
isnum <- sapply(inc_df, is.numeric)
inc_df[isnum] <- apply(inc_df[isnum], 2, GroupedMedian, ...)
и в этом случае худшее преобразование, которое вы получите, будет integer
- в numeric
, вероятно, приемлемое (и обратимое) преобразование.