2017-02-27 49 views
1

我有所有相同結構的列表的列表,我想更改第二層中每個列表的一個元素。換句話說,我有一個包含對象x,y & z的列表。該列表在另一個列表中重複多次。我需要在每個列表中更改x。做這個的最好方式是什麼?使用lapply更改列表的列表

我目前的做法是創建一個小功能,執行我想要的更改,然後重新創建列表。但是有什麼讓我覺得有更簡單的方法來做到這一點?

下面的代碼顯示了我的方法,這對我的玩具例子來說很好 - 但是對象更加複雜的真實上下文,所以我不想多次重新創建它,因爲我只更改一個值。我可以這樣做,它只是感覺錯綜複雜。

l = list(x = 1:3, y = "a", z = 9) 
test = list(l, l, l) 

standardize = function(obj){ 
    obj$x = obj$x/max(obj$x) 
    list(obj$x, obj$y, obj$z) 
} 

lapply(test, function(e) standardize(e)) 

回答

3

只需返回修改的obj而不是重新創建列表。

standardize = function(obj){ 
    obj$x <- obj$x/max(obj$x) 
    obj 
} 

獎勵:obj元素的名稱現在保留。

+0

非常感謝!現在感覺有點傻! – SamPassmore

1

隨着purrr:

library(purrr) 

test2 <- test %>% map(map_at, 'x', ~.x/max(.x)) 

test2 <- test %>% map(update_list, x = ~x/max(x)) 

無論哪種方式,你會得到

str(test2) 
## List of 3 
## $ :List of 3 
## ..$ x: num [1:3] 0.333 0.667 1 
## ..$ y: chr "a" 
## ..$ z: num 9 
## $ :List of 3 
## ..$ x: num [1:3] 0.333 0.667 1 
## ..$ y: chr "a" 
## ..$ z: num 9 
## $ :List of 3 
## ..$ x: num [1:3] 0.333 0.667 1 
## ..$ y: chr "a" 
## ..$ z: num 9 
0

鑑於你的列表的大小已經是固定的,這是一種情況,一個簡單的for循環也很適合這個任務。

for(i in seq_along(test)){ 
    test[[i]]$x <- test[[i]]$x/max(test[[i]]$x) 
} 

我時鐘此爲比lapply溶液慢僅僅0.8毫秒。