Умножьте вложенный список на значение и затем добавьте в столбец вложенного списка переменную группировки - PullRequest
1 голос
/ 17 марта 2020

У меня большой столбик с одним столбцом вложенного списка. Каждый элемент столбца вложенного списка имеет 10 000 итераций, и я хотел бы применить функцию к этим элементам, а затем суммировать их по группам.

Я создал минимальный воспроизводимый пример ниже

tibble(a = list(c(1,2),c(3,4), c(5,6), c(7,8)),
   b = c(2,3, 4, 2),
   c = c(1,1, 2, 2))

Сначала я хотел бы умножить каждый элемент на x $ a на x $ b. Это должно дать мне

tibble(a = list(c(2,4), c(9,12), c(20,24), c(14,16)),
   b = c(2,3, 4, 2),
   c = c(1,1,2,2))

Наконец, я хотел бы сгруппировать по x $ c, а затем добавить по значениям элемента этой группы. Это должно дать следующий результат

tibble(a = list(c(11,16), c(34,40)),
   c = c(1,2))

Как вы можете видеть, первый элемент x $ a - это сумма итераций, где x $ C == 1, то есть сумма вектора c (2,4 ) и c (9,12), дающих c (11,14)

Я думаю, что функция purrr :: map может сделать это, но борется с синтаксисом здесь

Любая помощь с благодарностью

Ответы [ 3 ]

0 голосов
/ 17 марта 2020

Один вариант, включающий dplyr и purrr, может быть:

df %>%
 mutate(a = map2(.x = a,
                 .y = b,
                 ~ .x * .y)) %>%
 group_by(c) %>%
 summarise(a = list(reduce(a, `+`)))

      c a        
  <dbl> <list>   
1     1 <dbl [2]>
2     2 <dbl [2]>
0 голосов
/ 17 марта 2020

И еще один вариант, используя tidyverse:

library(tidyverse)

df <- tibble(a = list(c(1,2),c(3,4), c(5,6), c(7,8)),
       b = c(2,3, 4, 2),
       c = c(1,1, 2, 2)) %>% 
      unnest() %>% 
      mutate(a = a*b) %>% 
      group_by(c) %>% 
      mutate(a = c(rep(nth(a,1) + nth(a,3), 2), rep(nth(a,2) + nth(a,4),2))) %>% 
      unique() %>% 
      summarize(a = list(a))

>       df
# A tibble: 2 x 2
      c a        
  <dbl> <list>   
1     1 <dbl [2]>
2     2 <dbl [2]>
0 голосов
/ 17 марта 2020

Мы можем преобразовать в «длинный» формат путем unnest, используя столбец «a», выполнить умножение и затем summarise, чтобы получить sum

library(dplyr)
library(tidyr)
library(data.table)
dat2 <- dat %>%
          mutate(rn = row_number()) %>% 
          unnest(c(a)) %>%
          group_by(rn) %>% 
          mutate(a1 = c(first(a) * first(b), last(a) * last(b))) %>% 
          group_by(c, grp = rowid(rn)) %>% 
          summarise(a = sum(a1))  %>%
          group_by(c) %>%
          summarise(a = list(a))
# A tibble: 2 x 2
#      c a        
#   <dbl> <list>   
#1     1 <dbl [2]>
#2     2 <dbl [2]>

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

dat %>% 
    unnest_wider(c(a)) %>% 
    group_by(c)  %>%
    summarise_at(vars(starts_with('..')), ~ sum(. * b)) 

или в версии devel dplyr

dat2 <- dat %>%
          unnest_wider(c(a)) %>% 
          group_by(c)  %>% 
          condense(a = across(starts_with('..'), ~ sum(. * b),
              names = "a{col}") %>% unlist(use.names = FALSE))

dat2
# A tibble: 2 x 2
# Rowwise:  c
#      c a        
#  <dbl> <list>   
#1     1 <dbl [2]>
#2     2 <dbl [2]>

dat2$a
#[[1]]
#[1] 11 16

#[[2]]
#[1] 34 40

In base R мы можем сделать

stack(lapply(split(Map(`*`, dat$a, dat$b), dat$c),
       function(x) do.call(`+`, x)))
#  values ind
#1     11   1
#2     16   1
#3     34   2   
#4     40   2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...