在R中的嵌套列表中分配具有相同名称的值

问题描述 投票:4回答:3

我想为具有相同名称的嵌套列表中的特定元素分配相同的值。如果元素在嵌套列表中不存在,我也想创建该元素,但在我的示例中没有显示。

例如,假设我有:

ls <- list(a = list(e1 = "value1.1", e2 = "value1.2"),
           b = list(e1 = "value2.1", e2 = "value2.2"))

我想将值“相同的值”分配给名为e1的子列表中的所有元素,以便最终得到所需的输出:

list(a = list(e1 = "same value", e2 = "value1.2"),
     b = list(e1 = "same value", e2 = "value2.2")
> ls
  $a
  $a$e1
  [1] "same value"

  $a$e2
  [1] "value1.2"


  $b
  $b$e1
  [1] "same value"

  $b$e2
  [1] "value2.2"

经过研究,我在包modify_depth()中找到了函数purrr,它将函数应用于嵌套列表,但不会赋值。

我唯一的另一个解决方案是这样做:

ls2 <- list()
for(sublist in ls){
  sublist[["e1"]] <- "same value"
  ls2 <- c(ls2, list(sublist))
}
names(ls2) <- names(ls)
ls <- ls2
rm(ls2)

注意:在循环之后,ls中没有分配“相同的值”,所以我必须创建ls2。我可以把它变成一个函数,但我确信有更好的方法可以做到这一点,没有for循环。

谢谢你的帮助!

r nested-lists
3个回答
3
投票

来自mapreplacepurrr

library(purrr)
map(ls, ~replace(., "e1", "same value"))

或与modify_depth

modify_depth(ls, 1, ~replace(., "e1", "same value"))

replace也与lapply合作:

lapply(ls, replace, "e1", "same value")

输出:

$a
$a$e1
[1] "same value"

$a$e2
[1] "value1.2"


$b
$b$e1
[1] "same value"

$b$e2
[1] "value2.2"

关于modify_depth的好处是你可以选择深度,而maplapply只下降一个级别:

ls2 <- list(c = list(a1 = list(e1 = "value1.1", e2 = "value1.2")),
            d = list(a1 = list(e1 = "value2.1", e2 = "value2.2")))

modify_depth(ls2, 2, ~replace(., "e1", "same value"))

输出:

$c
$c$a1
$c$a1$e1
[1] "same value"

$c$a1$e2
[1] "value1.2"


$d
$d$a1
$d$a1$e1
[1] "same value"

$d$a1$e2
[1] "value2.2"

编辑:如果我们想要将值向量应用于e1的每个ls2元素,modify_depth将无效,因为它没有map2变体。相反,我会在顶层使用两层mapmap2,在第二层使用map

vec <- c("newvalue1.1", "newvalue2.1")

map2(ls2, vec, ~map(.x, replace, "e1", .y))

输出:

$c
$c$a1
$c$a1$e1
[1] "newvalue1.1"

$c$a1$e2
[1] "value1.2"


$d
$d$a1
$d$a1$e1
[1] "newvalue2.1"

$d$a1$e2
[1] "value2.2"

1
投票

我们可以使用lapply迭代列表元素,然后使用[和逻辑运算符进行相等==我们可以找到我们想要改变的值

> lapply(ls, function(x){
    x[names(x)=="e1"] <- "same.value"
    x
  } )
$`a`
$`a`$`e1`
[1] "same.value"

$`a`$e2
[1] "value1.2"


$b
$b$`e1`
[1] "same.value"

$b$e2
[1] "value2.2"

-1
投票

Razxswpoi在R中保留,所以我建议在列表中使用另一个名称,我的替代方案是:

ls
© www.soinside.com 2019 - 2024. All rights reserved.