在两个嵌套对象上映射函数

时间:2019-06-17 19:22:20

标签: r dplyr purrr

我正在尝试将函数dplyr::mutate映射到数据集中包含的两组嵌套小动作上。我的目标是通过使用嵌套的db$data.y中相应的系数为嵌套在db$data.x中的每个tibble添加新列。

下面,我提供了一个可复制的示例。 db的每一行都指向我们正在验证的不同比例。 db$data.x中的嵌套小标题包含将用于执行进一步计算的方差分量。 db$data.y中的嵌套小标题包含相同的两列,其中每行的场合数(从1到10)和评分器(从1到2)的组合是不同的。

library(dplyr)
library(purrr)

coefficients <- data.frame(Scale = rep(1:5, each = 5), 
                           Component = rep(c("R", "S", "T", "RxS", "SxT"), 5), 
                           Value = rep(c(2, 4, 7, 3, 5, 5, 6, 7, 3, 5, 2, 6, 3, 6, 4, 7, 3, 7, 12, 8, 7, 11, 14, 9, 2))) %>% 
                           group_by(Scale) %>% nest()

sim.data <- data.frame(Scale = rep(1:5, each = 20), 
                       Occasion = rep(1:10, 2), 
                       Rater = rep(1:2, each = 10)) %>% 
                       group_by(Scale) %>% nest()

db <- left_join(coefficients, sim.data, by = "Scale")

#> db
# A tibble: 5 x 3
#  Scale data.x           data.y           
#  <int> <list>           <list>           
#1     1 <tibble [5 x 2]> <tibble [20 x 2]>
#2     2 <tibble [5 x 2]> <tibble [20 x 2]>
#3     3 <tibble [5 x 2]> <tibble [20 x 2]>
#4     4 <tibble [5 x 2]> <tibble [20 x 2]>
#5     5 <tibble [5 x 2]> <tibble [20 x 2]>

#> db$data.x[[1]]
# A tibble: 5 x 2
#  Component Value
#  <fct>     <dbl>
#1 R             2
#2 S             4
#3 T             7
#4 RxS           3
#5 SxT           5

#> db$data.y[[1]]
# A tibble: 20 x 2
#   Occasion Rater
#      <int> <int>
# 1        1     1
# 2        2     1
# 3        3     1
# 4        4     1
# 5        5     1
# 6        6     1
# 7        7     1
# 8        8     1
# 9        9     1
#10       10     1
#11        1     2
#...

最终目标是为每个标度计算db$data.y$Abs列,我们需要使用db$data.x中包含的方差成分。我可以分别为每个秤执行此操作,但是这似乎非常耗时。有没有人可以帮助您?

db$data.y[[1]] %>% 
     mutate(Abs = db$data.x[[1]][[1,2]] / db$data.y[[1]]$Occasion + 
                  db$data.x[[1]][[2,2]] / db$data.y[[1]]$Rater + 
                  db$data.x[[1]][[3,2]] / (db$data.y[[1]]$Occasion * db$data.y[[1]]$Rater))

# A tibble: 20 x 3
#   Occasion Rater Abs
#      <int> <int> <dbl>
# 1        1     1 13   
# 2        2     1  8.5 
# 3        3     1  7   
# 4        4     1  6.25
# 5        5     1  5.8 
# 6        6     1  5.5 
# 7        7     1  5.29
# 8        8     1  5.12
# 9        9     1  5   
#10       10     1  4.9 

我尝试使用purrr::map2,但是,如果我没有记错的话,它可以在同一个嵌套对象的两列上工作,而在这种情况下,我要处理两个不同的嵌套对象。我也很乐意考虑其他解决方案。

1 个答案:

答案 0 :(得分:2)

我认为可以使用map2()是正确的,但是您需要在mutate()中使用它,以便可以将两个嵌套列用作该函数的前两个参数。

然后,您可以将当前的mutate()代码用作map2()中的函数来修改data.y。您会看到我用外部data.y中具有相同名称的修改后的对象替换了当前的mutate()

类似这样的东西:

db %>%
    mutate(data.y = map2(data.x, 
                         data.y, 
                         ~mutate(.y, Abs = .x[[1, 2]]/.y$Occasion +
                                     .x[[2, 2]]/.y$Rater +
                                     .x[[3, 2]]/(.y$Occasion*.y$Rater))))

第一个数据帧看起来像

db %>%
    mutate(data.y = map2(data.x, 
                         data.y, 
                         ~mutate(.y, Abs = .x[[1, 2]]/.y$Occasion +
                                     .x[[2, 2]]/.y$Rater +
                                     .x[[3, 2]]/(.y$Occasion*.y$Rater)))) %>%
    pull(data.y) %>%
    pluck(1)

# A tibble: 20 x 3
   Occasion Rater   Abs
      <int> <int> <dbl>
 1        1     1 13   
 2        2     1  8.5 
 3        3     1  7   
 4        4     1  6.25
 5        5     1  5.8 
 6        6     1  5.5 
 7        7     1  5.29
 8        8     1  5.12
 9        9     1  5   
10       10     1  4.9 
...