将用户定义的函数应用于数据框列表中每个数据框的特定列?

Applying user defined functions to a specific column of each dataframe in a list of dataframes?

背景

大家好!我目前正在进行一个项目,该项目要求我通过 bootstrapping 模型残差来估计研究内方差,然后计算每个样本的 SEE。此过程必须逐个模型地完成。

我首先创建了一个数据帧列表,这些数据帧根据因子变量 model 使用以下代码 list.meta<- split(new.meta, new.meta$model) 进行拆分,其中每个数据帧都包含与单个模型相关的数据。我在下面提供了一个可重现的示例,并将其限制为 3 个模型;但是我的完整数据集包含 13 个。从那里我有两个用户定义的函数:一个用于计算 SEE,另一个生成 1000 bootstrapped 样本,使用先前定义的 SEE 函数计算每个样本的 SEE。为了透明起见,我也在下面提供了两者。

用户自定义函数

#Define SEE function 
SEE<- function(x){
  sqrt((sum(x)/(length(x)-2))^2)
}

#Define function for generating bootstrap samples and calculating SEE for each sample

Bootstrap<- function(x){
  int<- lapply(1:1000, function(i) sample(x, replace = T))
  Calc.SEE<- sapply(int, SEE)
}

其中 x 是给定数据帧中的 Residuals 列 'i'

数据

list(`1` = structure(list(Study = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), Model = c(1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L
), Residuals = c(26.96774194, 24.35483871, 15.74193548, 15.70967742, 
13.22580645, 12.87096774, 11.77419355, 10.67741935, 10.58064516, 
8.548387097, 8, 5.548387097, 5.35483871, 5.322580645, 2.612903226, 
1.483870968, 1.225806452, 0.258064516)), row.names = c(NA, 18L
), class = "data.frame"), `2` = structure(list(Study = c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L
), Model = c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L), Residuals = c(20.19354839, 16.5483871, 15.74193548, 
14.61290323, 7.064516129, 6.580645161, 5.64516129, 4.580645161, 
4.612903226, 3.612903226, 3.35483871, 2.741935484, 2.419354839, 
1.64516129, 1.35483871, 1.903225806, 0.516129032)), row.names = 19:35, class = "data.frame"), 
    `3` = structure(list(Study = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), Model = c(3L, 3L, 
    3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L
    ), Residuals = c(23.80645161, 17.41935484, 15.58064516, 13.22580645, 
    11.32258065, 10.4516129, 6.709677419, 6.193548387, 5.741935484, 
    4.870967742, 4.322580645, 2.709677419, 2.677419355, 1.032258065, 
    1.129032258, 0.451612903, 1.064516129)), row.names = 36:52, class = "data.frame"))

problem/question

所以,这是我的问题:我需要将 bootstrap 函数应用于每个模型的 residuals 列,输出最终是一个长度为 13 的列表(其中每个元素list 是由 1000 个 SEE 值组成的向量)或作为具有 13 列和 1000 行的 dataframe/matrix(第二个更好,因为它将用于进一步分析并且包将数据框作为输入)。

我认为最好的方法之一是通过 for 循环或 apply 系列中的一个函数。但是,就语法而言,当这些以列表格式嵌套时,我不知道如何将该函数实际应用于每个数据框的特定列

我试过的

  1. 尝试之一是使用 lapply 函数。
dat<- lapply(na.omit(new.data[[i]][, 4]), Bootstrap)

[[i]][, 4] 是我试图告诉 R 使用列表中第 i 个元素的第四列中的数据。这部分工作但返回长度为 18 的列表?一些列表元素也没有意义。

  1. 我正在研究的第二个选项是使用 for 循环:
for (i in 1:seq_along(new.data)){
result<- Bootstrap(new.data[[i]][,4])
return(result)
}

但这returns是一个错误

In 1:seq_along(new.data) :
  numerical expression has 13 elements: only the first used

我也不知道如何将结果实际保存为列表或矩阵格式,我的 for 循环技能可能需要更多的工作...所以就是这样。

可能会有一个非常简单的答案,所以在此先感谢您提出的所有建议。我真的需要加紧练习编码:)

你可以做到

dat <- lapply(new.data, function(dataFrameInList) {
    Bootstrap(na.omit(dataFrameInList[["Residuals"]]))
})

希望命名清晰易懂。在列表上使用 lapply 时,它会获取每个元素,在您的情况下 data.frames 我将 dataFrameInList 称为“循环变量”。然后,通过 dataFrameInList[["Residuals"]] 选择残差。或者,您可以使用 dataFrameInList[,"Residuals"]dataFrameInList[,4]。扔掉 NAs 并最终应用你的 Bootstrap-函数。