2016-12-10 2 views
1

С кадром данных, как показано нижеКак сохранить имена столбцов при динамическом прохождении столбцов кадра данных `aggregate`

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))) 

Я хочу объединить COLS 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) 

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

df2[, 1] V1 V2 

Как получить имена столбцов в исходном кадре данных в возвращаемом кадре данных?

ответ

2

Я буду принимать общий случай, когда у вас есть несколько 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 
+0

великое объяснение. вы получили LHS и RHS? LHS - это столбцы, по которым выполняется агрегация, а RHS - столбцы, которые должны быть агрегированы? – user3206440

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

  • Нет связанных вопросов^_^