将列表列中的自定义函数应用于另一个列表列的所有元素,并将结果分组到小块的列表列中以绘制小块

时间:2019-09-26 04:31:40

标签: r dplyr purrr

我有两个输入:一个是小标题,其中一列是其中具有自定义函数定义的列表列。该小标题还包含变量“ id”,该变量“ id”指示生成数据的一组特定参数。对于每个“ id”,此小标题中有 n 行,每行具有不同的自定义函数变体。

我想将该自定义函数应用于另一个输入的每个元素。这是一个列表列表(实际上是引用类实例,每个“ id”值都有一个观察值),我需要从中提取字段“ z”并将自定义函数应用于该列表。因此,每个“ z”都会重复 n 次,并且每次对其应用不同版本的自定义函数。

最终目的是要有一个嵌套的小记号,我可以在ggplot中使用该小记号为每个“ id”值创建一个单独的图。

我已经使用下面的代码实现了这一点,但是对于大表(> 10M行),结果非常慢,因为最后进行了“嵌套”操作,将“ z”和“ zfn”列分组为一个列表小标题列。

问题是我是否可以避免该嵌套嵌套序列,而仍然以可用于ggplot调用的小标题列表列结束?

library(tidyverse)

# First input, includes the list column of custom function definitions 'fndef' 
dfA <- tibble(
  id = rep(1:2, each = 3),
  fndef = list(function(x) x + 1, function(x) x + 2, function(x) x + 3, 
               function(x) x + 4, function(x) x + 5, function(x) x + 6)
  )

# Second input is a list of instances of a reference class from which we 
# are going to extract a field 'z' later on. 
# Since each instance matches 'id', the element 'z' needs to be repeated 
.Model <- setRefClass(
  "Model",

  fields = list(id = 'numeric',
                z = 'matrix')
  )

dfB <- list(.Model(id = 1, z = as.matrix(rnorm(10))), 
            .Model(id = 2, z = as.matrix(rnorm(10))))

# Combine inputs, extract 'z' from 'dfB', apply 'fndef' to each 'z' to return 'zfn' and 
# group both 'z' and 'zfn' into a tibble.
dfC <- dfA %>%
  group_by(id) %>%
  nest() %>%
  ungroup() %>%
  mutate(z = map(.x = dfB, .f = ~.x$z)) %>%
  unnest(cols = data) %>%
  mutate(zfn = map2(.x = .$z, .y = .$fndef, .f = ~.y(.x))) %>%
  select(-fndef) %>%
  unnest(cols = c(z, zfn)) %>%
  group_by(id) %>%
  nest()

# Ultimate goal is to plot, one plot per 'id'.
dfD <- dfC %>% 
  group_by(id) %>%
  mutate(plot = map2(data, id, ~ggplot(data = .x, mapping = aes(x = z, y = zfn)) +
                       geom_line()))

0 个答案:

没有答案