【问题标题】:Extract values from list of arbitrary depth从任意深度列表中提取值
【发布时间】:2020-08-18 15:59:32
【问题描述】:

我有一个凌乱的、高度嵌套的列表:

m <- list('form' = list('elements' = list('name' = 'Bob', 'code' = 12), 'name' = 'Mary', 'code' = 15))
> m
$form
$form$elements
$form$elements$name
[1] "Bob"

$form$elements$code
[1] 12


$form$name
[1] "Mary"

$form$code
[1] 15

如何从对象m 中提取namecode,无论namecode 在列表中的嵌套方式如何?

预期输出:

# A tibble: 2 x 2
  name   code
  <chr> <dbl>
1 Bob      12
2 Mary     15

【问题讨论】:

  • 也许x &lt;- unlist(m); data.frame(name=x[endsWith(names(x), "name")], code=x[endsWith(names(x), "code")])
  • 也许this SO question 的答案会有所帮助。

标签: r


【解决方案1】:

1) rrapply 使用rrapplym 展平,给出r,然后使用tapplyunlist(r) 的名称和代码字段分开,使用c 删除维度,转换为 data.frame 并设置列的顺序。

请注意,这不会硬编码为名称和代码,并且可以与其他字段和字段数量一起使用。

library(rrapply)

r <- rrapply(m, f = c, how = "flatten")
nms <- names(r)
as.data.frame(c(tapply(unname(r), nms, unlist)))[unique(nms)]

给予:

  name code
1  Bob   12
2 Mary   15

上面最后两行代码的替代方案是:

out <- unstack(stack(r))
out[] <- lapply(out, type.convert)

如果m 中除了namecode 之外还有其他我们希望忽略的字段,则使用它来代替上面定义r 的语句:

cond <- function(x, .xname) .xname %in% c("name", "code")
r <- rrapply(m, cond, c, how = "flatten")

2) Base R 下面是一个 base R 解决方案,它取消列出m,然后使用tapply,如(1)按names(r) 的后缀分组。与 (1) 一样,这是一种未硬编码为 namecode 的通用方法。请注意,工具随 R 一起提供,因此它是 Base R 的一部分。

r <- unlist(m)
nms <- tools::file.ext(names(r))
as.data.frame(c(tapply(unname(r), nms, unlist)))[unique(nms)]

【讨论】:

    【解决方案2】:

    这有助于将列表格式化为数据框,然后对其进行整形:

    library(tidyverse)
    #Process
    y1 <- as.data.frame(lapply(m,unlist),stringsAsFactors = F)
    y1$id <- rownames(y1)
    rownames(y1)<-NULL
    #Dplyr mutation
    y1 %>% mutate(Var=ifelse(grepl('name',id,),'name',
                             ifelse(grepl('code',id),'code',NA))) %>%
      select(-id) %>% group_by(Var) %>%
      mutate(i=1:n())%>% pivot_wider(names_from = Var,values_from = form) %>%
      select(-i) %>% mutate(code=as.numeric(code))
    

    输出:

    # A tibble: 2 x 2
      name   code
      <chr> <dbl>
    1 Bob      12
    2 Mary     15
    

    【讨论】:

      猜你喜欢
      • 2021-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-18
      • 1970-01-01
      • 2021-10-20
      相关资源
      最近更新 更多