«объект не найден» для столбцов, добавленных в столбец списка с помощью purrr pmap - PullRequest
0 голосов
/ 04 марта 2020

У меня есть набор данных, к которому я хочу применить следующие операции:

  1. Вложить данные по набору столбцов
  2. Изменить столбец списка «data» на широкоформатный формат
  3. Используйте столбец списка «данные» и значения в столбцах группировки, чтобы создать новый столбец в столбце списка «данные», используя в качестве входных данных также столбцы, созданные в разделе 2.

1 & 2 работают нормально, используя purrr и dplyr, но на шаге 3, когда я пытаюсь сослаться на один из столбцов, созданных на шаге 2, выдается ошибка «объект не найден». Это работает нормально, если я ссылаюсь только на столбцы в столбце списка «данных», которые уже существовали до шага 2. Если я проверяю содержимое столбца списка после шага 2, все, на что есть ссылка в шаге 3, так почему же новый столбец не распознается ?

Представляет

library(tidyverse)

mtcarsT <- mtcars %>% as_tibble() %>%
  group_by(cyl, gear, vs) %>%
  mutate(cp_flag = rep(c('C', 'P'), length.out = n())) %>%
# step 1, works fine.
  nest() %>%
  mutate(data = map(data, ~ .x %>%
                      group_by(mpg, disp, hp, drat, am, carb) %>%
# step 2, also works fine, generates new columns 'wt_C', 'wt_P', 'qsec_C', 'qsec_P' in 'data'
                      pivot_wider(names_from = cp_flag, values_from = wt:qsec) %>%
                      ungroup()))

# > mtcarsT[1,]
# A tibble: 1 x 4
# Groups:   cyl, vs, gear [1]
#    cyl    vs  gear data             
#  <dbl> <dbl> <dbl> <list>           
# 1     6     0     4 <tibble [1 x 10]>
#
# > mtcarsT$data[[1]]
# A tibble: 1 x 10
#    mpg  disp    hp  drat    am  carb  wt_C  wt_P qsec_C qsec_P
#  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>  <dbl>  <dbl>
#  1    21   160   110   3.9     1     4  2.62  2.88   16.5   17.0


# step 3A: this one works fine when only referencing columns in 'data' that already existed before step 2.
mtcarsT %>%
  mutate(data = pmap(.l = list(a = data, b = vs, c = gear),
                     .f = function(a, b, c) a %>% 
                       dplyr::mutate(vs_gear = carb - b + c)))  

# > .Last.value$data[[1]]
# A tibble: 1 x 11
#    mpg  disp    hp  drat    am  carb  wt_C  wt_P qsec_C qsec_P vs_gear
#  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>  <dbl>  <dbl>   <dbl>
# 1    21   160   110   3.9     1     4  2.62  2.88   16.5   17.0       8


# Step 3B: this is what I want to do, use the column 'wt_P' in the 'data' list column 
# that was created in step 2 along with other columns 'vs' and 'gear' in the nested tibble, 
# but it throws the error 'object wt_P not found'
mtcarsT %>%
  mutate(data = pmap(.l = list(a = data, b = vs, c = gear),
                     .f = function(a, b, c) a %>% 
                       dplyr::mutate(vs_gear = wt_P - b + c)))

# Error: object 'wt_P' not found
# Called from: mutate_impl(.data, dots, caller_env())


'''

I'm using R 3.6.2 x64 with tidyverse 1.3.0 inside RStudio 1.2.5033 on Windows 10.




1 Ответ

1 голос
/ 04 марта 2020

Пример работает, как и ожидалось, но проблема присутствует в самом шаге 1.

Чтобы показать, что пример работает, вы можете изменить wt_P на wt_C, и он работает.

library(tidyverse)

mtcarsT %>%
   mutate(data = pmap(.l = list(a = data, b = vs, c = gear),
                      .f = function(a, b, c)
                             a %>% dplyr::mutate(vs_gear = wt_C - b + c)))

#     cyl    vs  gear data              
#   <dbl> <dbl> <dbl> <list>            
# 1     6     0     4 <tibble [1 × 11]> 
# 2     4     1     4 <tibble [8 × 11]> 
# 3     6     1     3 <tibble [2 × 11]> 
#....

Проблема на шаге 1 заключается в том, что вы делаете

mtcars %>% as_tibble() %>%
    group_by(cyl, gear, vs) %>%
    mutate(cp_flag = rep(c('C', 'P'), length.out = n()))

есть определенные группы с одним наблюдением, которые вообще не получают значение P.

mtcars %>%  count(cyl, gear, vs)

# A tibble: 10 x 4
#     cyl  gear    vs     n
#   <dbl> <dbl> <dbl> <int>
# 1     4     3     1     1
# 2     4     4     1     8
# 3     4     5     0     1
# 4     4     5     1     1
# 5     6     3     1     2
# 6     6     4     0     2
# 7     6     4     1     2
# 8     6     5     0     1
# 9     8     3     0    12
#10     8     5     0     2 

Следовательно, wt_P для них не рассчитывается и возвращает ошибку, тогда как wt_C - нет. Если вы измените порядок в rep с c('C', 'P') на c('P', 'C'), вы получите ошибку для wt_C, и wt_P будет работать, как ожидалось.


Чтобы добавить отсутствующий столбец, мы можем сделать:

mtcars %>%
   group_by(cyl, gear, vs) %>% 
   mutate(cp_flag = rep(c('C', 'P'), length.out = n())) %>% 
   nest() %>% 
   mutate(data = map(data, ~{ 
                       temp <- .x %>% 
                       group_by(mpg, disp, hp, drat, am, carb) %>% 
                       pivot_wider(names_from = cp_flag, values_from = wt:qsec, 
                       values_fill = list(wt = NA, qsec = NA)) %>% 
                       ungroup()
                       temp[setdiff(cols, names(temp))] <- NA;temp
         })) 


#     cyl    vs  gear data              
#   <dbl> <dbl> <dbl> <list>            
# 1     6     0     4 <tibble [1 × 10]> 
# 2     4     1     4 <tibble [8 × 10]> 
# 3     6     1     3 <tibble [2 × 10]> 
# 4     8     0     3 <tibble [12 × 10]>
# 5     6     1     4 <tibble [2 × 10]> 
# 6     4     1     3 <tibble [1 × 10]> 
# 7     4     0     5 <tibble [1 × 10]> 
# 8     4     1     5 <tibble [1 × 10]> 
# 9     8     0     5 <tibble [2 × 10]> 
#10     6     0     5 <tibble [1 × 10]> 

Таким образом, все они имеют одинаковое количество столбцов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...