想象一下,我正在處理一個串列串列,如下所示:
lol <- list(l1 = list(a = c(1:3), b = c(4:6), c = 2),
l2 = list(a = c(1:3), b = c(4:6)),
l3 = list(a = c(1:3), b = c(4:6)))
我想應用一個函式,說:
foo <- function(x){
sum(x$a, x$b)*x$c
}
從第一個串列產生的元素c需要附加到串列中的下一個元素 ( l2) 才能使函式作業。所以演算法是:
A) 計算sum(a, b)乘以c-> 結果newc。
B)附加newc到下一個串列,呼叫它c
C) 重復
我知道如何回圈執行此操作,如下所示:
for(i in 1:length(lol)){
s <- lol[[i]]
s[["newc"]] <- foo(s)
lol[[i]] <- list()
lol[[i]] <- s
if((i 1)<(length(lol) 1)){
lol[[i 1]][["c"]] <- lol[[i]][["newc"]]
}
}
就我而言,我必須使用更多資料(串列中的更多串列)和迭代很多次(最少 100 次)來執行此操作,這給了我很高的運行時間(在某些試驗中大約為 2 秒)。由于我需要將其與越來越多的資料一起使用,因此我希望有此回圈的替代方案。
編輯:謝謝你的回答。不過,我需要澄清一下,我的串列中需要 c 和 newc。之前不清楚。謝謝你。
您對如何在沒有回圈的情況下解決此問題有任何想法嗎?謝謝!
uj5u.com熱心網友回復:
該問題可以重新表述為根據串列的前一個元素更新串列的當前元素。
回圈可以簡化為單行:
lol <- list(l1 = list(a = c(1:3), b = c(4:6), c = 2),
l2 = list(a = c(1:3), b = c(4:6)),
l3 = list(a = c(1:3), b = c(4:6)))
foo <- function(x){
sum(x$a, x$b)*x$c
}
for(i in seq_along(lol)[-1]){
lol[[i]][["c"]] <- foo(lol[[i - 1L]])
}
lol
#> $l1
#> $l1$a
#> [1] 1 2 3
#>
#> $l1$b
#> [1] 4 5 6
#>
#> $l1$c
#> [1] 2
#>
#>
#> $l2
#> $l2$a
#> [1] 1 2 3
#>
#> $l2$b
#> [1] 4 5 6
#>
#> $l2$c
#> [1] 42
#>
#>
#> $l3
#> $l3$a
#> [1] 1 2 3
#>
#> $l3$b
#> [1] 4 5 6
#>
#> $l3$c
#> [1] 882
由reprex 包于 2022-05-11 創建(v2.0.1)
編輯
這是另一個解決方案,基于Ritchie Sacramento 的評論。
lol <- list(l1 = list(a = c(1:3), b = c(4:6), c = 2),
l2 = list(a = c(1:3), b = c(4:6)),
l3 = list(a = c(1:3), b = c(4:6)))
foo <- function(x, y) {
sum(y$a, y$b)*x
}
newc <- Reduce(foo, lol[-1], init = lol[[1]][["c"]], accumulate = TRUE)
Map(\(x, newc) {x[["c"]] <- newc; x}, lol, newc)
#> $l1
#> $l1$a
#> [1] 1 2 3
#>
#> $l1$b
#> [1] 4 5 6
#>
#> $l1$c
#> [1] 2
#>
#>
#> $l2
#> $l2$a
#> [1] 1 2 3
#>
#> $l2$b
#> [1] 4 5 6
#>
#> $l2$c
#> [1] 42
#>
#>
#> $l3
#> $l3$a
#> [1] 1 2 3
#>
#> $l3$b
#> [1] 4 5 6
#>
#> $l3$c
#> [1] 882
由reprex 包于 2022-05-11 創建(v2.0.1)
編輯 2
在結果中也有newc以下任何一項都可以。
請注意,上述解決方案具有不同的功能foo。第二個是 Ritchie Sacramento 評論中的功能,現已洗掉,我已在上面的Reduce/Map解決方案中復制了該功能。
解決方案1,與newc
foo <- function(x){
sum(x$a, x$b)*x$c
}
for(i in seq_along(lol)[-1L]){
lol[[i]][["c"]] <- foo(lol[[i - 1L]])
lol[[i]][["newc"]] <- foo(lol[[i]])
}
lol
解決方案2,與newc
foo <- function(x, y) {
sum(y$a, y$b)*x
}
newc <- Reduce(foo, lol, init = lol[[1]][["c"]], accumulate = TRUE)
Map(\(x, c, newc) {
x[["c"]] <- c
x[["newc"]] <- newc
x
}, lol, newc[-length(newc)], newc[-1])
lol
uj5u.com熱心網友回復:
我不會使用回圈:
lol <- lapply(lol, \(x) c(x, c=lol[[1]]$c))
lapply(lol, foo)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/473803.html
上一篇:雪花在回圈內呼叫存盤程序N次
