Как сохранить имена столбцов при динамической передаче столбцов фрейма данных в "агрегат"
С фреймом данных, как показано ниже
df1 <- data.frame(a=seq(1.1,9.9,1.1), b=seq(0.1,0.9,0.1),
c=rev(seq(10.1, 99.9, 11.1)))
Я хочу объединить столбцы b
а также c
от a
Так что я бы сделал что-то вроде этого
aggregate(cbind(b,c) ~ a, data = df1, mean)
Это сделало бы это. Однако я хочу обобщить без жестко закодированных имен столбцов, как в функции.
myAggFunction <- function (df, col_main, col_1, col_2){
return (aggregate(cbind(df[,col1], df[,col2]) ~ df[,col_main], df, mean))
}
myAggFunction(df, 1, 2, 3)
Проблема у меня заключается в том, что имена столбцов возвращенного фрейма данных, как показано ниже
df2[, 1] V1 V2
Как получить имена столбцов в исходном фрейме данных в возвращенном фрейме данных?
1 ответ
Я буду предполагать общий случай, когда у вас есть несколько LHS (левые стороны), а также несколько RHS (правые стороны).
Использование метода data.frame
## S3 method for class 'data.frame'
aggregate(x, by, FUN, ..., simplify = TRUE, drop = TRUE)
Если вы передадите объект как именованный список, вы получите сохраненные имена. Так что не обращайтесь к вашему фрейму данных с [, ]
, но с []
, Вы можете построить свою функцию как:
## `LHS` and `RHS` are vectors of column names or numbers giving column positions
fun1 <- function (df, LHS, RHS){
## call `aggregate.data.frame`
aggregate.data.frame(df[LHS], df[RHS], mean)
}
Все еще используете метод "формулы"?
## S3 method for class 'formula'
aggregate(formula, data, FUN, ...,
subset, na.action = na.omit)
Это немного утомительно, но мы хотим построить хорошую формулу с помощью:
as.formula( paste(paste0("cbind(", toString(LHS), ")"),
paste(RHS, collapse = " + "), sep = " ~ ") )
Например:
LHS <- c("y1", "y2", "y3")
RHS <- c("x1", "x2")
as.formula( paste(paste0("cbind(", toString(LHS), ")"),
paste(RHS, collapse = " + "), sep = "~") )
# cbind(y1, y2, y3) ~ x1 + x2
Если вы кормите эту формулу aggregate
, вы получите приличные имена столбцов.
Так что сконструируйте свою функцию так:
fun2 <- function (df, LHS, RHS){
## ideally, `LHS` and `RHS` should readily be vector of column names
## but specifying vector of numeric positions are allowed
if (is.numeric(LHS)) LHS <- names(df)[LHS]
if (is.numeric(RHS)) RHS <- names(df)[RHS]
## make a formula
form <- as.formula( paste(paste0("cbind(", toString(LHS), ")"),
paste(RHS, collapse = " + "), sep = "~") )
## call `aggregate.formula`
stats:::aggregate.formula(form, df, mean)
}
замечание
aggregate.data.frame
самый лучший aggregate.formula
это обертка и позвонит model.frame
внутри, чтобы сначала построить фрейм данных.
Я даю метод "формулы" в качестве опции, потому что способ, которым я создаю формулу, полезен для lm
, так далее.
Простой, воспроизводимый пример
set.seed(0)
dat <- data.frame(y1 = rnorm(10), y2 = rnorm(10),
x1 = gl(2,5, labels = letters[1:2]))
## "data.frame" method with `fun1`
fun1(dat, 1:2, 3)
# x1 y1 y2
#1 a 0.79071819 -0.3543499
#2 b -0.07287026 -0.3706127
## "formula" method with `fun2`
fun2(dat, 1:2, 3)
# x1 y1 y2
#1 a 0.79071819 -0.3543499
#2 b -0.07287026 -0.3706127
fun2(dat, c("y1", "y2"), "x1")
# x1 y1 y2
#1 a 0.79071819 -0.3543499
#2 b -0.07287026 -0.3706127