我有一个参与者ID及其访问的嵌套列表。对于每次访问的每个参与者,测量10个变量10次,并且数据结构类似于R代码给出的模拟数据。对于参与者[[1]],我们有3次访问对应[[1]] [[1]],[[1]] [[2]]和[[1]] [[3]]。类似地,对于参与者2.我想在每次访问时为每个患者计算第25和第75个分位数,并将其存储在如下的长数据帧中。任何帮助表示赞赏。
set.seed(23)
ll <- lapply(1:2, FUN=function(i) replicate(3, matrix(rnorm(20), ncol=2), simplify=FALSE))
df<-data.frame(id=numeric(0),visit=numeric(0),col1.lower.ptile=numeric(0),col1.upper.ptile=numeric(0),col2.lower.ptile=numeric(0),col2.upper.ptile=numeric(0))
答案 0 :(得分:2)
这是使用*apply
函数的船载的基本R方法。
# use R rapply to get in the nested list and apply pull out the quantiles from the columns
myRList <- rapply(ll, function(x) apply(x, 2, quantile, probs=c(.25, .75)), how="list")
rapply
进入嵌套结构,apply
按列拉出每个矩阵的分位数。例如,对于第一位患者,这将返回
myRList[1]
[[1]]
[[1]][[1]]
[,1] [,2]
25% 0.08238097 -0.5795292
75% 1.08541924 0.2856748
[[1]][[2]]
[,1] [,2]
25% -0.5572163 -0.9983007
75% 0.6329706 0.2190313
[[1]][[3]]
[,1] [,2]
25% -0.7966075 -0.4823147
75% 0.8378379 0.9661969
请注意,每个度量都在一列中,这就是R将数据存储在矩阵中的方式。因此,我们可以使用c
将数据拉出到所需的格式,以去除矩阵类。要将其放入data.frame,请使用vapply
和c
从每个矩阵返回一个向量,使用lapply
运行每个患者并返回一个向量列表。然后使用带有rbind.data.frame
的do.call返回所需的data.frame。
dat <- cbind(id=rep(seq_along(ll), lengths(ll)),
do.call(rbind.data.frame,
lapply(myRList, function(x) t(vapply(x, c, FUN.VALUE=numeric(4))))))
返回
dat
id V1 V2 V3 V4
1 1 0.08238097 1.08541924 -0.5795292 0.2856748
2 1 -0.55721633 0.63297057 -0.9983007 0.2190313
3 1 -0.79660754 0.83783794 -0.4823147 0.9661969
4 2 -1.07159858 0.02937252 -0.4670312 0.6528579
5 2 -0.44806361 0.52761202 0.1081107 1.1419628
6 2 -0.72854367 0.55997887 -0.1397759 0.6157683
如果您发现可以信任结果,我们可以将其简化为单个操作,如下所示。
dat <- cbind.data.frame(id=rep(seq_along(ll), lengths(ll)),
matrix(rapply(ll, function(x) apply(x, 2, quantile,
probs=c(.25, .75))), ncol=4))
然后根据需要设置变量名称。
答案 1 :(得分:1)
类似的解决方案,语法稍微简单:
with(new.env(), {
# compute quantiles
q <- lapply(ll, lapply, apply, 2, quantile, prob = c(0.25, 0.75))
# simplify to array
a <- simplify2array(unlist(q, recursive = FALSE))
# return dataframe
data.frame(id = rep(seq_along(ll), lengths(ll)),
visit = unlist(lapply(lengths(ll), seq)),
col1.lower.ptile = a[1, 1, ],
col1.upper.ptile = a[2, 1, ],
col2.lower.ptile = a[1, 2, ],
col2.upper.ptile = a[2, 2, ])
}) -> df
df
# id visit col1.lower.ptile col1.upper.ptile col2.lower.ptile col2.upper.ptile
#1 1 1 -0.18320744 0.42239195 -0.1075228 0.82134959
#2 1 2 -0.30466626 0.72310699 -1.1047154 -0.05519628
#3 1 3 -0.69026613 0.08553756 -0.4338562 0.34916939
#4 2 1 0.08335451 0.59375988 -1.1392453 0.45905958
#5 2 2 -0.81078650 0.23024319 -0.8819546 0.33385295
#6 2 3 -1.15689954 0.82117652 -0.2739212 0.61445726
请注意,我将整个内容放在with
中,以便中间结果q
和a
在结尾处自动销毁,但这并非绝对必要。