【问题标题】:unlist column of lists of single values单值列表的 unlist 列
【发布时间】:2018-11-07 15:38:01
【问题描述】:

我一直在为聚类生成一些特征,并且需要基于随时间提交的客户索赔的相关系数。我使用此代码通过在嵌套的数据块上运行 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) : Columncoeffmust be length 27768 (the number of rows) or one, not 21949。这是因为unlist() 没有返回相同数量的元素。我使用purrr::flattenunlist(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"))

【问题讨论】:

  • 我想你可能想要map_dbl(3) 而不是map(3)。如果您输入reproducible example,我将能够验证。
  • 我正在制作一个虚拟数据框,但是,我似乎无法强制 R 将该列设为列表。我之前使用过map_dbl,但它并没有像我期望的那样工作。我得到Error in mutate_impl(.data, dots) : Evaluation error: Result 20 is not a length 1 atomic vector
  • 绝对需要一个示例数据集。你可以dput() 的一部分provProfileTemp 并将其添加到问题中吗?当我使用mtcars 进行分组回归时,map_dbl() 似乎工作正常:mtcars %&gt;% group_by(cyl) %&gt;% nest() %&gt;% mutate(fit = map(data, ~ lm(mpg ~ wt, data = .x)), results = map(fit, summary, correlation = TRUE), coef = results %&gt;% map(c("correlation")) %&gt;% map_dbl(3))
  • 最后有没有试过unnest(coeff)
  • 根据我得到的错误,unnest on coeff 不适用于列表。

标签: r dplyr purrr


【解决方案1】:

您对丢失某些数据和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, dots) 中的错误:评估错误:结果 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(),尽管这对你的场景来说更难。我最终关注了this answer,但我确信还有其他方法/工具可以做到这一点。

只要相关矩阵中没有第三个值,我就会返回 NA_real_

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

【讨论】:

  • 哇。伟大的,彻底的解释。谢谢@aosmith 它也非常适用于我的数据。感谢所有的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-06
  • 2015-04-20
  • 2019-09-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-03
相关资源
最近更新 更多