unlist столбец списков отдельных значений - PullRequest
0 голосов
/ 07 ноября 2018

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

provProfileTemp <- byProvProfile %>% 
  mutate(date = ymd(paste(Year, Month, "01", sep = "-"))) %>% 
  select(-Month, -Year) %>% 
  group_by(AccountNumber, date) %>% 
  count() %>% 
  group_by(AccountNumber) %>% 
  mutate(total_claims = sum(n)) %>% 
  ungroup() %>% 
  mutate(numeric_date = as.numeric(date)/(24*60*60)) %>% # POSIX conversion for summary(lm)
  select(AccountNumber, numeric_date, claims = n, total_claims) %>% 
  nest(-AccountNumber, -total_claims)

coeffs <- provProfileTemp %>% 
  mutate(
    fit = map(provProfileTemp$data, ~lm(numeric_date ~ claims, data = .)), 
    results = map(fit, summary, correlation = TRUE), 
    coeff = results %>% map(c("correlation")) %>% map(3)
  ) %>% 
 select(AccountNumber, coeff, total_claims) 

В верхнем блоке создаются переменные, необходимые для строки регрессии, и вкладываются данные в таблицу с номером счета, общими требованиями и фрагментом данных для регрессии. Используя purrr::map во втором блоке, я могу уместить строку, получить результаты из сводки и вывести коэффициент из сводки.

Результаты верны и работают нормально, однако новый столбец представляет собой список с единственным значением коэффициента в нем. Я не могу сжать список, чтобы использовать новый столбец как коэффициент, а не список. Использование unlist() дает эту ошибку: Error in mutate_impl(.data, dots) : Column coeff must be length 27768 (the number of rows) or one, not 21949. Это происходит потому, что unlist() не возвращает одинаковое количество элементов. У меня были похожие результаты с функциями, такими как purrr::flatten или unlist(lapply(coeff, "[[", 1)).

Любые предложения о том, как правильно сгладить список в одно значение или подойти к проблеме другим способом, который не требует генерации такого коэффициента? Любая помощь очень ценится. Спасибо.

Вот как выглядят данные:

AccountNumber       coeff  total_claims
        <int>      <list>         <int>
           16   <dbl [1]>           494     
           19   <dbl [1]>           184     
           45   <dbl [1]>            81...

Вот фиктивные данные:

provProfileTemp <- structure(list(AccountNumber = c(1L, 1L, 1L, 1L, 
     1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 
     2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L
     ), Year = c(2018L, 2017L, 2018L, 2018L, 2018L, 2017L, 2018L, 
     2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 
     2018L, 2018L, 2018L, 2018L), Month = c(4L, 11L, 1L, 1L, 3L, 10L, 
     1L, 3L, 7L, 1L, 5L, 10L, 5L, 2L, 4L, 4L, 4L, 3L, 2L, 1L)), .Names =               c("AccountNumber", 
     "Year", "Month"), row.names = c(NA, -20L), class = c("tbl_df", 
     "tbl", "data.frame"))

1 Ответ

0 голосов
/ 07 ноября 2018

Ваш комментарий о том, что некоторые данные отсутствуют и lm() ничего не производит, является ключевым здесь.

Во-первых, давайте создадим сценарий только с одним значением объясняющей переменной для одной группы. Это воспроизводит ошибки с map_dbl() и unnest () `и т. Д.

library(purrr)
library(tidyr)
library(dplyr)

mtcars$wt2 = mtcars$wt
mtcars$wt2[mtcars$cyl == 4] = NA
mtcars$wt2[3] = 1

mtcars %>% 
    group_by(cyl) %>% 
    nest() %>% 
    mutate(fit = map(data, ~ lm(mpg ~ wt2, data = .x)), 
           results = map(fit, summary, correlation = TRUE), 
           coef = results %>% map(c("correlation")) %>% map_dbl(3))

Ошибка в mutate_impl (.data, точки): Ошибка оценки: Результат 2 не атомный вектор длины 1.

Это потому, что одним из результатов является NULL.

mtcars %>% 
    group_by(cyl) %>% 
    nest() %>% 
    mutate(fit = map(data, ~ lm(mpg ~ wt2, data = .x)), 
           results = map(fit, summary, correlation = TRUE), 
           coef = results %>% map(c("correlation")) %>% map(3)) %>%
    pull(coef)

[[1]]
[1] -0.9944458

[[2]]
NULL

[[3]]
[1] -0.983668

Таким образом, вам нужно заменить NULL чем-то (или удалить строки без достаточного количества данных перед выполнением подбора модели, что может быть самым простым решением). Я часто использую possibly() в подобных ситуациях, хотя это было сложнее для вашего сценария. Я закончил тем, что следовал этому ответу , но я уверен, что есть другие способы / инструменты, чтобы сделать это.

Я возвращаю NA_real_ всякий раз, когда в корреляционной матрице нет 3-го значения.

mtcars %>% 
    group_by(cyl) %>% 
    nest() %>% 
    mutate(fit = map(data, ~ lm(mpg ~ wt2, data = .x)), 
           results = map(fit, summary, correlation = TRUE), 
           coef = results %>% map(c("correlation")) %>% 
               map_dbl(., possibly(~.x[3], NA_real_)))

# A tibble: 3 x 5
    cyl data               fit      results             coef
  <dbl> <list>             <list>   <list>             <dbl>
1     6 <tibble [7 x 11]>  <S3: lm> <S3: summary.lm>  -0.994
2     4 <tibble [11 x 11]> <S3: lm> <S3: summary.lm>  NA    
3     8 <tibble [14 x 11]> <S3: lm> <S3: summary.lm>  -0.984
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...