【问题标题】:Build nested named list from list in R从R中的列表构建嵌套命名列表
【发布时间】:2020-12-06 14:49:41
【问题描述】:

我正在尝试准备稍后在我的脚本中需要的数据结构。假设我在一个图域中,并且我的节点(有时只有 1 个,但大多数是 2 个甚至 3 个)有名称(例如,"left""right""center")。名称存储在一个变量中:

origin_target_list <- c("left", "center", "right", "")

鉴于上面包含三个项目的列表,我正在尝试动态创建此数据结构:

origin_target_combinations <- list(
  left = list(    # origin is left
    right = c(),  # target is right
    center = c(), # target is center
    unknown = c() # target is somewhere else / unknown
  ),
  right = list(
    left = c(),
    center = c(),
    unknown = c()
  ),
  center = list(
    left = c(),
    right = c(),
    unknown = c()
  ),
  unknown = list( # origin is unknown
    left = c(),   # target is left
    center = c(), # target is center
    right = c()   # target is right
  )
)

编辑:约束是原点和目标不能相同。因此,origin_target_list 中的每个元素加上“未知”都应该组合在一起。

类似,只有一个元素的列表:origin_target_list &lt;- c("center") 只会创建未知情况:

origin_target_combinations <- list(
  unknown = list(
    left = c(),
    center = c(),
    right = c()
  )
)

我知道这是一个复杂的问题,我现在正在自己研究解决方案...我会根据我的尝试不断更新这篇文章...

【问题讨论】:

  • PS:如果您对数据结构有更好的想法,请随时更改它。仍处于实施阶段...
  • 为了有一个更好的主意,我们必须知道你到底想要达到什么目的。

标签: r arrays list


【解决方案1】:

你可以这样做

# assign function to create the list
create_list <- function(args, val = c())
  setNames(
    lapply(args, function(x)
      setNames(rep(list(val), length(args) - 1L), setdiff(args, x))), 
    args)

# use the function
str(create_list(c("left", "center", "right", "unknown")))
#R> List of 4
#R>  $ left  :List of 3
#R>   ..$ center: NULL
#R>   ..$ right : NULL
#R>   ..$ unknown: NULL
#R>  $ center:List of 3
#R>   ..$ left  : NULL
#R>   ..$ right : NULL
#R>   ..$ unknown: NULL
#R>  $ right :List of 3
#R>   ..$ left  : NULL
#R>   ..$ center: NULL
#R>   ..$ unknown: NULL
#R>  $ unknown:List of 3
#R>   ..$ left  : NULL
#R>   ..$ center: NULL
#R>   ..$ right : NULL

# you can change the type and the element names like so
str(create_list(c("cat", "dog", "bird"), numeric()))
#R> List of 3
#R>  $ cat :List of 2
#R>   ..$ dog : num(0) 
#R>   ..$ bird: num(0) 
#R>  $ dog :List of 2
#R>   ..$ cat : num(0) 
#R>   ..$ bird: num(0) 
#R>  $ bird:List of 2
#R>   ..$ cat: num(0) 
#R>   ..$ dog: num(0) 

【讨论】:

  • 也是一个不错的解决方案。谢谢!
  • 开箱即用!
【解决方案2】:

这是一个使用lapply的简单实现:

make_list <- function(branches)
{
  setNames(lapply(branches, function(origin)
  {
    blank <- list(left = c(), right = c(), center = c(), unknown = c())
    blank[!(names(blank) %in% origin)]
  }), branches)
}

产量

make_list(c("left", "right", "center", "unknown"))
#> $left
#> $left$right
#> NULL
#> 
#> $left$center
#> NULL
#> 
#> $left$unknown
#> NULL
#> 
#> 
#> $right
#> $right$left
#> NULL
#> 
#> $right$center
#> NULL
#> 
#> $right$unknown
#> NULL
#> 
#> 
#> $center
#> $center$left
#> NULL
#> 
#> $center$right
#> NULL
#> 
#> $center$unknown
#> NULL
#> 
#> 
#> $unknown
#> $unknown$left
#> NULL
#> 
#> $unknown$right
#> NULL
#> 
#> $unknown$center
#> NULL

reprex package (v0.3.0) 于 2020 年 8 月 17 日创建

【讨论】:

  • 这很聪明!
【解决方案3】:

这个函数应该做你想做的事情。但是您必须用不仅仅是一个空向量来填充列表元素,因为如果它们为空,它们将再次被删除。所以,我用一个包含单个 NA 的向量填充它们:

make_dynlist = function(nodes){
  l = list("unknown"=list("right"=c(NA),
                          "left"=c(NA),
                          "center"=c(NA)))
  if(length(nodes)>1){
    for(n in c(nodes)){
      l[[n]]=list()
      for(d in nodes){
        if(n!=d){
          l[[n]][[d]]=c(NA)
        }
      }
    }
  }
  
  return(l)
}

输出将是:

> make_dynlist(c("left", "center", "right"))
$unknown
$unknown$right
[1] NA

$unknown$left
[1] NA

$unknown$center
[1] NA


$left
$left$center
[1] NA

$left$right
[1] NA


$center
$center$left
[1] NA

$center$right
[1] NA


$right
$right$left
[1] NA

$right$center
[1] NA


> make_dynlist(c("center"))
$unknown
$unknown$right
[1] NA

$unknown$left
[1] NA

$unknown$center
[1] NA

【讨论】:

  • 抱歉,我刚刚编辑了我的问题以实际包含 unknown 以供目标使用。但到目前为止,这看起来不错!谢谢
猜你喜欢
  • 2021-01-12
  • 2013-05-12
  • 1970-01-01
  • 2022-11-17
  • 2016-06-04
  • 1970-01-01
  • 2022-01-02
  • 1970-01-01
  • 2019-05-20
相关资源
最近更新 更多