dplyr resume quando o retorno da função é com valor vetorial?

odplyr::summarize() A função pode aplicar funções arbitrárias sobre os dados, mas parece que a função deve retornar um valor escalar. Estou curioso para saber se existe uma maneira razoável de lidar com funções que retornam um valor vetorial sem fazer várias chamadas para a função.

Aqui está um exemplo mínimo um tanto bobo. Considere uma função que fornece vários valores, como:

f <- function(x,y){
  coef(lm(x ~ y, data.frame(x=x,y=y)))
}

e dados parecidos com:

df <- data.frame(group=c('A','A','A','A','B','B','B','B','C','C','C','C'), x=rnorm(12,1,1), y=rnorm(12,1,1))

Eu gostaria de fazer algo como:

df %>% 
group_by(group) %>%
summarise(f(x,y))

e retorne uma tabela que possui 2 colunas adicionadas para cada um dos valores retornados, em vez da coluna 1 usual. Em vez disso, esses erros com:Expecting single value

Claro que podemos obter vários valores dedlpyr::summarise() fornecendo o argumento da função várias vezes:

f1 <- function(x,y) coef(lm(x ~ y, data.frame(x=x,y=y)))[[1]]
f2 <- function(x,y) coef(lm(x ~ y, data.frame(x=x,y=y)))[[2]]

df %>% 
group_by(group) %>%
summarise(a = f1(x,y), b = f2(x,y))

Isso fornece a saída desejada:

  group         a            b
1     A 1.7957245 -0.339992915
2     B 0.5283379 -0.004325209
3     C 1.0797647 -0.074393457

mas codificar dessa maneira é ridiculamente bruto e feio.

data.table lida com este caso de forma mais sucinta:

dt <- as.data.table(df)
dt[, f(x,y), by="group"]

mas cria uma saída que estende a tabela usando linhas adicionais em vez de colunas adicionais, resultando em uma saída que é confusa e difícil de trabalhar:

 group           V1
1:     A  1.795724536
2:     A -0.339992915
3:     B  0.528337890
4:     B -0.004325209
5:     C  1.079764710
6:     C -0.074393457

Claro que existem mais clássicosapply estratégias que poderíamos usar aqui,

sapply(levels(df$group), function(x) coef(lm(x~y, df[df$group == x, ])))


                     A            B           C
(Intercept)  1.7957245  0.528337890  1.07976471
y           -0.3399929 -0.004325209 -0.07439346

mas isso sacrifica tanto a elegância quanto suspeito a velocidade do agrupamento. Em particular, observe que não podemos usar nossa função predefinidaf neste caso, mas precisa codificar o agrupamento na definição da função.

Tem algumadplyr função para lidar com este caso? Caso contrário, existe uma maneira mais elegante de lidar com esse processo de avaliação de funções com valor vetorial em um data.frame por grupo?

questionAnswers(2)

yourAnswerToTheQuestion