2014-02-12 189 views
4

我有一個記錄列表:是否可以修改列表元素?

z <- list(list(a=1),list(a=4),list(a=2)) 

,我嘗試將字段添加到他們每個人。 唉,既不

lapply(z,function(l) l$b <- 1+l$a) 

也不

for(l in z) l$b <- 1+l$a 

修改z

在這個簡單的情況下,我當然可以,做

z <- lapply(z,function(l) c(list(b= 1+l$a),l)) 

但很快失控,當名單有更多的嵌套:

z <- list(list(a=list(b=1)),list(a=list(b=4)),list(a=list(b=2))) 

我如何把它變成

list(list(a=list(b=1,c=2)),list(a=list(b=4,c=5)),list(a=list(b=2,c=3))) 

沒有重複整個結構的定義? z的每個元素都有很多字段,而不僅僅是a;和z[[10]]$a有許多子字段,而不僅僅是b

回答

4

你的第一個代碼示例不修改列表,因爲您需要在您的通話返回列表lapply

z <- list(list(a=1),list(a=4),list(a=2)) 
expected <- list(list(a=1, b=2), list(a=4, b=5), list(a=2, b=3)) 
outcome <- lapply(z,function(l) {l$b <- 1+l$a ; l}) 
all.equal(expected, outcome) 
# [1] TRUE 

在雙重嵌套例如,可以內lapply使用lapply,再次確保返回在內部lapply名單:

z <- list(list(a=list(b=1)),list(a=list(b=4)),list(a=list(b=2))) 
expected <- list(list(a=list(b=1, c=2)), list(a=list(b=4, c=5)), list(a=list(b=2, c=3))) 
obtained <- lapply(z, function(l1) { lapply(l1, function(l2) {l2$c = l2$b+1 ; l2 })}) 
all.equal(expected, obtained) 
# [1] TRUE 
+0

實際上,你不需要嵌套'lapply'; 'lapply(z,function(l){l $ a $ c < - l $ a $ b + 3; l})'工作得很好! – sds

2

另外,有些令人費解,選項:

z <- list(list(a=1),list(a=4),list(a=2)) 
res <- list(list(a=list(b=1,c=2)),list(a=list(b=4,c=5)),list(a=list(b=2,c=3))) 
res1 <- rapply(z,function(x) list(b = x,c = x+1),how = "replace") 
> all.equal(res,res1) 
[1] TRUE 

我只是說錯綜複雜,因爲rapply可能會有時棘手(至少對我來說)。

+0

使用all.equal來驗證預期輸出的巧妙技巧 - 它會帶來更簡潔的迴應! – josliber