R + dplyr nest + purr - 在数据帧行中的嵌套之间评估模型

时间:2017-01-13 11:13:06

标签: r dplyr nls purrr tidyverse

由于目前还没有开源数据,因此很难想出一个可重复的示例,而且我不确定我是否可以共享我拥有的数据。我会尽力解释它,如果这不起作用,我可能需要一些时间来模拟一些数据。希望它是一个简单的解决方案,但是......

背景

我正在忙着为我工作的领域(https://github.com/mathesong/kinfitr)创建一个用于动力学建模的R包。我尽我所能努力使所有东西都适合整理工具。但是,有一个特定的用例,我无法弄清楚如何做到这一点,因为它涉及从几种不同格式中提取相当不同结构的数据,并在模型中将它们拉在一起。

在页面的README中,我提供了参考区域模型的解决方案,其中所有输入的长度相同,我可以使用以下工作流程:

data %>% 
  gather() %>%
  group_by() %>%
  do()

问题

但是,对于动脉模型,输入参数如下:

  1. 脑动力学数据:时间,数值,权重 - 相同长度的每个向量,在本例中为38

  2. 血液动力学数据:血液输入 - 4096行×4列的数据框。为方便起见,所有模型都将其作为数据框读取,并且已经插入了所有信息。

  3. 每个模型都需要输入所有三个向量,以及血液输入数据框。

    我目前将所有数据存储在列表中,每个测量都有一个元素。列表的每个元素包含1.数据框,其中包含大脑动力学数据(大脑的每个区域,比如3个区域),以及时间和权重,以及2.包含血液输入数据的数据框。因此,我创建了我的最终数据框

    datdf <- map(dat, 'braindf') %>%  # Extract the brain data
      bind_rows(.id = "id") %>%   # Add an id column
      select(PET = id, Times = Times, Weights=weights, R1 = Region1, R2 = Region2, R3 = Region3) %>%  # Rename and select columns
      group_by(PET) %>%    # Group by each measurement
      nest() %>%    # Nest everything
      rename(braindata=data) %>%     # Rename
      mutate(Subjname = stringr::str_extract(....)), # Add subject acronym
             PETNo = as.numeric(stringr::str_extract(....)), # Add measurement number
             input=map(dat, 'bloodinput'))  # Add blood input data frame as a nested column
    

    这让我得到以下

    # A tibble: 6 × 5
         PET         braindata Subjname PETNo               bloodinput
       <chr>            <list>    <chr> <dbl>                   <list>
    1 s1_1 <tibble [38 × 6]>     s1       1 <data.frame [4,096 × 4]>
    2 s1_2 <tibble [38 × 6]>     s1       2 <data.frame [4,096 × 4]>
    3 s2_1 <tibble [38 × 6]>     s2       1 <data.frame [4,096 × 4]>
    4 s2_2 <tibble [38 × 6]>     s2       2 <data.frame [4,096 × 4]>
    5 s1_1 <tibble [38 × 6]>     s3       1 <data.frame [4,096 × 4]>
    6 s2_2 <tibble [38 × 6]>     s3       2 <data.frame [4,096 × 4]>
    

    每个大脑数据包含以下内容:

    head(datdf[1,]$braindata[[1]])
    
    # A tibble: 6 × 6                   
        Times   Weights R1      R2      R3
        <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
    1   0   0   0.00E+00    0.00E+00    0.00E+00
    2   22  0.3 1.12E-03    4.14E-03    4.78E-04
    3   32  0.5 5.61E-01    4.08E-01    7.38E-01
    4   42  0.7 4.53E+01    4.50E+01    5.61E+01
    5   52  0.7 8.12E+01    8.07E+01    1.02E+02
    6   62  0.9 1.03E+02    1.04E+02    1.31E+02
    

    从这一点来说,我无法弄清楚如何为每一行拟合模型。

    这就是我的尝试:

    R1_outcomes <- datdf %>%
      group_by(PET) %>%  # or rowwise()
      mutate(onetcmout = onetcm(t_tac=.$braindata[[1]]$Times/60,
                                 tac=.$braindata[[1]]$R1,
                                 input=.$bloodinput,
                                 weights=.$braindata[[1]]$Weights))
    
    R1_outcomes <- datdf %>%
    rowwise() %>%
    do(onetcmout = onetcm(t_tac=.$braindata[[1]]$Times/60,
                               tac=.$braindata[[1]]$R1,
                               input=.$bloodinput,
                               weights=.$braindata[[1]]$Weights))
    

    我确定通过地图功能可以做到这一点,但我无法弄清楚如何做到这一点。

    我真的很感激有关如何做到这一点的任何建议。提前感谢任何人!

0 个答案:

没有答案