簡體   English   中英

使用 lapply 更改 arguments

[英]Using lapply with changing arguments

R 教科書繼續提倡使用 lapply 代替循環。 即使對於具有 arguments 之類的功能,這也很容易

lapply(somelist, f, a=1, b=2) 

但是如果 arguments 根據列表元素發生變化怎么辦? 假設我的 somelist 包括:

somelist$USA
somelist$Europe
somelist$Switzerland

另外還有anotherlist具有相同區域的列表,我想在這些不斷變化的 arguments 中使用 lapply? 例如,當 f 是比率計算時,這可能很有用。

lapply(somelist, f, a= somelist$USA, b=anotherlist$USA) 

除了循環之外,還有其他方法可以有效地穿過這些區域嗎?

編輯:我的問題似乎是我嘗試使用以前編寫的 function 沒有索引...

ratio <-function(a,b){
z<-(b-a)/a
return(z)
}

這導致

lapply(data,ratio,names(data))

這是行不通的。 也許其他人也可以從這個錯誤中吸取教訓。

應用於列表名稱而不是列表元素。 例如:

somelist <- list('USA'=rnorm(10), 'Europe'=rnorm(10), 'Switzerland'=rnorm(10))
anotherlist <- list('USA'=5, 'Europe'=10, 'Switzerland'=4)
lapply(names(somelist), function(i) somelist[[i]] / anotherlist[[i]])

編輯:

您還詢問是否有一種“除了循環”可以“有效地”執行此操作的方法。 您應該注意,應用不一定會更有效。 效率可能取決於您的內部 function 有多快。 如果要對列表的每個元素進行操作,則需要一個循環,無論它是否隱藏在 apply() 調用中。 檢查這個問題: R 的應用系列不僅僅是語法糖嗎?

我上面給出的例子可以重寫為一個 for 循環,你可以做一些簡單的基准測試:

fun1 <- function(){
    lapply(names(somelist), function(i) somelist[[i]] / anotherlist[[i]])
}
fun2 <- function(){
    for (i in names(somelist)){
        somelist[[i]] <- somelist[[i]] / anotherlist[[i]] 
    }
    return(somelist)
}
library(rbenchmark)

benchmark(fun1(), fun2(),
          columns=c("test", "replications",
          "elapsed", "relative"),
          order="relative", replications=10000)

我機器上的基准測試的 output 是這樣的:

    test replications elapsed relative
1 fun1()        10000   0.145 1.000000
2 fun2()        10000   0.148 1.020690

雖然這不是一個真正的工作應用程序並且功能不是現實的任務,但您可以看到計算時間的差異可以忽略不計。

你只需要弄清楚要lapply()結束什么。 在我們重寫f()以獲取不同的 arguments 之后,列表的names()就足夠了:

somelist <- list(USA = 1:10, Europe = 21:30,
                 Switzerland = seq(1, 5, length = 10))
anotherlist <- list(USA = list(a = 1, b = 2), Europe = list(a = 2, b = 4),
                    Switzerland = list(a = 0.5, b = 1))

f <- function(x, some, other) {
    (some[[x]] + other[[x]][["a"]]) * other[[x]][["b"]]
}

lapply(names(somelist), f, some = somelist, other = anotherlist)

給予:

R> lapply(names(somelist), f, some = somelist, other = anotherlist)
[[1]]
 [1]  4  6  8 10 12 14 16 18 20 22

[[2]]
 [1]  92  96 100 104 108 112 116 120 124 128

[[3]]
 [1] 1.500000 1.944444 2.388889 2.833333 3.277778 3.722222 4.166667 4.611111
 [9] 5.055556 5.500000

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM