Агрегировать таблицу, применяя функцию из нескольких столбцов - PullRequest
0 голосов
/ 11 июня 2018

Учитывая следующую таблицу df, с категориальными переменными, отмеченными x1 и x2, и числовыми измерениями, отмеченными y1, y2 и y3:

df <- data.frame(x1=sample(letters[1:3], 20, replace=TRUE),
           x2=sample(letters[4:6], 20, replace=TRUE),
           y1=rnorm(20), y2=rnorm(20), y3=rnorm(20))

Я быхотел бы применить к нему функцию 3 числовых измерений y по категориальным переменным x.Например, следующая функция, где входные данные y - это таблица из 3 столбцов, которая должна выводить один новый столбец:

f <- function(y){   sum((y[,1] - y[,2]) / y[,3]) }

Я пробовал с aggregate, dplyr, summarizeBy... безуспешно, так как кажется, что для каждого метода смешивание входных столбцов не вариант.Любая идея о том, как сделать это с такими функциями (например, с помощью агрегации)?

aggregate(data = df, y1 + y2 + y3 ~ x1 + x2, FUN = f)

Чтобы уточнить, ожидаемый результат можно получить с помощью чего-то вроде:

groups <- unique(df[,c("x1", "x2")]) # coocurences of explanatory variables
res <- c()
for (i in 1:nrow(groups)){ # get the subtables
  temp <- df[df$x1 == groups[i,1] & df$x2 == groups[i,2], c("y1", "y2", "y3")]
  res <- c(res, f(temp)) # apply function on subtables
}
groups$res <- res # aggregate results

Что не так уж и много для этого простого игрушечного примера, но очень непрактично с более сложными данными.

1 Ответ

0 голосов
/ 11 июня 2018

Проблема на входной стороне вашей функции.То, как вы его указали, ожидает фрейм данных.

Возможное решение - передать функции список столбцов.С небольшим изменением вашей функции:

f <- function(y) sum((y[[1]] - y[[2]]) / y[[3]]) 

Теперь вы можете использовать его в dplyr -цепи:

df %>% 
  group_by(x1, x2) %>% 
  summarise(sum_y = f(list(y1, y2, y3)))

, что дает:

# A tibble: 9 x 3
# Groups:   x1 [?]
  x1    x2     sum_y
  <fct> <fct>  <dbl>
1 a     d      1.20 
2 a     e      0.457
3 a     f     -9.46 
4 b     d     -1.11 
5 b     e     -0.176
6 b     f     -1.34 
7 c     d     -0.994
8 c     e      3.38 
9 c     f     -2.63
...