I have a vector of values that I wish to use to modify a consistent component of a nested list. Currently I'm using a for loop to do this which is proving quite slow and I'm wondering if there's a faster way to do it.
By way of reproducible example:
#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
Which creates a list that looks like this:
$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
Now let's say the second maths paper for all students is remarked:
#New Data
MathsRemark <- c(24, 50, 45) #assume in correct (alphabetical) order
And we wish to modify their existing second maths score for these new values. My current solution for doing this is:
#Current Slow Solution
for (i in 1:length(Students)) {
ExamResults[[i]][["Maths"]][[2]] <- MathsRemark[i]
}
On larger datasets this is proving very slow. Is anyone aware of a faster way to do this? I've been taught to avoid using for loops where vectorising is possible but I can't figure out how to vectorise this problem. Any ideas would be much appreciated.
One option is Map()
.
Map(function(x, y) { x$Maths[2] <- y; x }, ExamResults, MathsRemark)
A second option is to unlist, replace, and relist.
u <- unlist(ExamResults)
relist(replace(u, endsWith(names(u), "Maths2"), MathsRemark), ExamResults)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With