这将很难提出一个可重复的示例,因为目前还没有开源数据,而且我不确定我是否可以共享我拥有的数据。我会尽力解释它,如果这不起作用,我可能会花一些时间来模拟一些数据。希望这是一个简单的解决方案...
背景
我正忙着为我工作的领域(https://github.com/mathesong/kinfitr)创建一个用于动力学建模的 R 包。我正在尽我所能让一切都适合 tidyverse 工具。但是,有一个特定的用例,我不知道该怎么做,因为它涉及以不同的结构从几种不同的格式中提取数据,然后在模型中将它们拉到一起。
在页面上的 README 中,我提供了参考区域模型的解决方案,其中所有输入的长度相同,我可以使用以下工作流程:
data %>%
gather() %>%
group_by() %>%
do()
问题
但是,对于动脉模型,输入参数如下:
脑动力学数据:时间、值、权重 - 每个向量的长度相同,在本例中为 38
血液动力学数据:血液输入 - 4096 行 x 4 列的数据框。为了方便起见,所有模型都将其作为数据帧读取,其中所有信息都已插入。
每个模型都需要所有三个向量的输入,以及血液输入数据框。
我目前将所有数据存储在一个列表中,每个测量都有一个元素。列表的每个元素都包含 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))
我确信有一种方法可以使用地图功能来做到这一点,但我不太清楚如何。
我真的很感激任何关于我如何能够做到这一点的建议。提前感谢任何人!