r - 如何使用 purrr 将计算列添加到嵌套数据框(列表列)

标签 r dplyr purrr

我想对嵌套数据框(存储为列表列)执行计算,并使用 purrr 函数将计算出的变量添加回每个数据框。我将使用此结果连接到其他数据,并保持紧凑有助于我更好地组织和检查它。我可以通过几个步骤来做到这一点,但似乎有一个我没有遇到过的解决方案。如果那里有解决方案,我无法轻松找到。

加载库 .示例需要以下软件包(在 CRAN 上可用):

library(dplyr)
library(purrr)
library(RcppRoll) # to calculate rolling mean

示例数据 有 3 个受试者,并随着时间的推移重复测量:
test <- data_frame(
  id= rep(1:3, each=20),
  time = rep(1:20, 3),
  var1 = rnorm(60, mean=10, sd=3),
  var2 = rnorm(60, mean=95, sd=5)
  )

将数据存储为嵌套数据框 :
t_nest <- test %>% nest(-id)

     id              data
  <int>            <list>
1     1 <tibble [20 x 3]>
2     2 <tibble [20 x 3]>
3     3 <tibble [20 x 3]>

执行计算 .我将根据数据计算多个新变量,尽管稍后可以扩展一个解决方案。每次计算的结果将是一个数字向量,与输入长度相同(n=20):
t1 <- t_nest %>% 
  mutate(var1_rollmean4 = map(data, ~RcppRoll::roll_mean(.$var1, n=4, align="right", fill=NA)),
         var2_delta4 = map(data, ~(.$var2 - lag(.$var2, 3))*0.095),
         var3 = map2(var1_rollmean4, var2_delta4, ~.x -.y))

     id              data var1_rollmean4 var2_delta4       var3
  <int>            <list>         <list>      <list>     <list>
1     1 <tibble [20 x 3]>     <dbl [20]>  <dbl [20]> <dbl [20]>
2     2 <tibble [20 x 3]>     <dbl [20]>  <dbl [20]> <dbl [20]>
3     3 <tibble [20 x 3]>     <dbl [20]>  <dbl [20]> <dbl [20]>

我的解决方案 是到 unnest这个数据,然后nest再次。这似乎没有任何问题,但似乎可能存在更好的解决方案。
t1 %>% unnest %>% 
  nest(-id)

     id              data
  <int>            <list>
1     1 <tibble [20 x 6]>
2     2 <tibble [20 x 6]>
3     3 <tibble [20 x 6]>

这个另一个解决方案( from SO 42028710 )很接近,但不完全是因为它是一个列表而不是嵌套的数据框:
map_df(t_nest$data, ~ mutate(.x, var1calc = .$var1*100))   

我使用 purrr Cheatsheet 找到了很多有用的信息但不能完全找到答案。

最佳答案

您可以再包装一次 mutate通过数据列进行映射并在每个嵌套的 tibble 中添加列时:

t11 <- t_nest %>% 
    mutate(data = map(data, 
        ~ mutate(.x, 
            var1_rollmean4 = RcppRoll::roll_mean(var1, n=4, align="right", fill=NA),
            var2_delta4 = (var2 - lag(var2, 3))*0.095,
            var3 = var1_rollmean4 - var2_delta4
        )
   ))

t11
# A tibble: 3 x 2
#     id              data
#  <int>            <list>
#1     1 <tibble [20 x 6]>
#2     2 <tibble [20 x 6]>
#3     3 <tibble [20 x 6]>
unnest-nest方法,然后重新排列里面的列:
nest_unnest <- t1 %>% 
    unnest %>% nest(-id) %>% 
    mutate(data = map(data, ~ select(.x, time, var1, var2, var1_rollmean4, var2_delta4, var3)))

identical(nest_unnest, t11)
# [1] TRUE

关于r - 如何使用 purrr 将计算列添加到嵌套数据框(列表列),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46436107/

相关文章:

r - 使用data.tables,尝试按列索引聚合数据

r - 查找先前行中小于和大于 r 中当前行值的最接近值

r - 从数据框中的两个字符类型行的组合创建一个新行

r - 提高循环内 bind_rows 的速度(3000 个数据帧)

返回 R 中地理加权回归 (GWR) 的全局 R2

r - 计算具有几乎相同名称的列对的差异(最后一个字符串不同)

r - 使用 dplyr 中的 group_by 函数来操作 data.frame 对象集

r - Tidyverse 按行绑定(bind)未命名向量列表的方法 - do.call(rbind,x) 等效

r - 使用自定义函数命名由 `nest` (tidyr) 创建的列中的项目

r - 使用嵌套数据框访问 purrr::map() 中的分组变量