我有一个列表列表(g
),如下所示。要从其中一个嵌入列表(例如第一个列表)中删除元素k
,我可以做:g[[1]]$k <- NULL
。
但是当我尝试从所有嵌入列表中删除元素k
时,我的lapply
代码失败了吗?是否有Base R修复程序?
g <- list(b1 = list(data.frame(a = 1:3), k = 4:6), b2 = list(data.frame(a = 8:9), k = 7:9))
lapply(1:length(g), function(i) g[[i]]$k <- NULL) ## FAILS to delete `k` from all embedded lists
答案 0 :(得分:3)
你可以
lapply(g, function(x) x[names(x) != "k"])
#$b1
#$b1[[1]]
# a
#1 1
#2 2
#3 3
#$b2
#$b2[[1]]
# a
#1 8
#2 9
或者
lapply(g, function(x) { x[names(x) == "k"] <- NULL; x })
答案 1 :(得分:3)
R是一种功能语言,因此传递了参数的副本,而不是指向它们的指针。函数不应在参数的“原始”上进行修改。因此,您不应假定对该函数内部访问的值所做的修改在该函数的环境之外将是“可见的”,除非存在对原始名称(或此处进行的替代名称)的赋值,除非 :
> g2 <- lapply(g, function(i){ i$k <- NULL; i})
> g2
$b1
$b1[[1]]
a
1 1
2 2
3 3
$b2
$b2[[1]]
a
1 8
2 9
还请注意:在将“ k”值归零后,需要返回修改后的元素。似乎更直接地传递实际元素而不是使用索引。 <-
和<<-
函数允许“不修改参数”的规则有一个隐含的例外。
答案 2 :(得分:2)
这里是discard
library(purrr)
map(g, ~ discard(.x, names(.x) == "k"))
#$b1
#$b1[[1]]
# a
#1 1
#2 2
#3 3
#$b2
#$b2[[1]]
# a
#1 8
#2 9
答案 3 :(得分:1)
类似于@ 42-:
lapply(g, '[[<-', 'k', NULL)
# $b1
# $b1[[1]]
# a
# 1 1
# 2 2
# 3 3
# $b2
# $b2[[1]]
# a
# 1 8
# 2 9