有没有一种快速的方法来修改R中嵌套列表的一致组件?

Wil*_*T-E 3 r nested-lists

我有一个值向量,希望用于修改嵌套列表的一致组件。目前,我正在使用for循环来执行此操作,事实证明它相当慢,并且我想知道是否有更快的方法可以执行此操作。

通过可重现的示例:

#Create Data and List
set.seed(100)
Students <- c("Amy", "Ben", "Caz")
Subject <- c("Maths", "English", "Science")

ExamResults <- lapply(Students, function (r) {
  Scores <- lapply(Subject, function(x) round(runif(4, 0, 100)))
  names(Scores) <- Subject
  Scores
})
names(ExamResults) <- Students
Run Code Online (Sandbox Code Playgroud)

这将创建一个如下所示的列表:

$Amy
$Amy$Maths
[1] 31 26 55  6

$Amy$English
[1] 47 48 81 37

$Amy$Science
[1] 55 17 62 88

$Ben
$Ben$Maths
[1] 28 40 76 67

$Ben$English
[1] 20 36 36 69

$Ben$Science
[1] 54 71 54 75

$Caz
$Caz$Maths
[1] 42 17 77 88

$Caz$English
[1] 55 28 49 93

$Caz$Science
[1] 35 95 70 89
Run Code Online (Sandbox Code Playgroud)

现在,我们要说所有学生的第二篇数学论文:

#New Data
MathsRemark <- c(24, 50, 45) #assume in correct (alphabetical) order
Run Code Online (Sandbox Code Playgroud)

我们希望针对这些新值修改其现有的第二数学分数。我目前的解决方案是:

#Current Slow Solution
for (i in 1:length(Students)) {
  ExamResults[[i]][["Maths"]][[2]] <- MathsRemark[i]
}
Run Code Online (Sandbox Code Playgroud)

在较大的数据集上,这证明非常慢。有人知道更快的方法吗?我被教导要避免在可能进行矢量化的情况下使用for循环,但是我不知道如何对这个问题进行矢量化。任何想法将不胜感激。

Ric*_*ven 5

一种选择是Map()

Map(function(x, y) { x$Maths[2] <- y; x }, ExamResults, MathsRemark)
Run Code Online (Sandbox Code Playgroud)

第二种选择是取消列出,替换和重新列出。

u <- unlist(ExamResults)
relist(replace(u, endsWith(names(u), "Maths2"), MathsRemark), ExamResults)
Run Code Online (Sandbox Code Playgroud)