数据框到字典,如 R 中的嵌套列表

Dataframe to dictionary like nested list in R

我正在尝试创建一个从 data.frame 开始的嵌套字典。

dta <- data.frame(x = c('A','B','A','B'),
                  y = c('P','Q','Q','P'),
                  z = c(89,12,34,56)
                  ) |> print()
    #>   x y  z
    #> 1 A P 89
    #> 2 B Q 12
    #> 3 A Q 34
    #> 4 B P 56
    

以下不是我要找的

  as.list(dta)
    #> $x
    #> [1] "A" "B" "A" "B"
    #> $y
    #> [1] "P" "Q" "Q" "P"
    #> $z
    #> [1] 89 12 34 56

我想做的是使用 make_nested_list 创建一个查找 table 这样 nested_dta = make_nested_list(dta)nested_dta['A']['P'] 将输出 89 很接近,但对我的情况没有用。 我正在尝试在 base R 中执行此操作,以便它更具可读性。 dplyr 可以做到这一点,但看起来很罗嗦 library(tidyvserse);dta %>% filter(x=='A',y=='P') %>% pull(z)。还有其他用例可能会受益于基础 R 公式。有没有更好的方法来创建嵌套字典?谢谢。

您可以定义自定义函数


dta <- data.frame(x = c('A','B','A','B'), y = c('P','Q','Q','P'), z = c(89,12,34,56) )

lt <- function(x, y, df = dta){
  return(df[df[1]==x & df[2] == y, 3])
}

lt('A', 'P')

[1] 89

如果您想创建一个嵌套列表,tidyverse 选项可以是

dta <- data.frame(x = c('A','B','A','B'), y = c('P','Q','Q','P'), z = c(89,12,34,56) )

library(tidyverse)
dta %>%
  split(.$x, drop = TRUE) %>%
  map(~ split(.x, .x$y, drop = T)) %>%
  map_depth(2, ~.x %>% pull(z)) -> nested_list

nested_list
#> $A
#> $A$P
#> [1] 89
#> 
#> $A$Q
#> [1] 34
#> 
#> 
#> $B
#> $B$P
#> [1] 56
#> 
#> $B$Q
#> [1] 12

reprex package (v2.0.0)

于 2021-06-27 创建

您可以使用 setNamesMap 获得所需的嵌套列表。

nested_list <- Map(setNames, setNames(as.list(dta$z), dta$x), dta$y)
nested_list

#$A
# P 
#89 

#$B
# Q 
#12 

#$A
# Q 
#34 

#$B
# P 
#56 

检查输出 -

nested_list[['A']][['P']]
#[1] 89

nested_list[['B']][['Q']]
#[1] 12

by 中使用 split

make_nested_list <- function(d) by(d, dta$x, \(b) split(b$z, b$y))
nested_dta <- make_nested_list(dta)
nested_dta[['A']][['P']]
# [1] 89
nested_dta$A$P
# [1] 89

为了完整起见,可以使用 keyed data.table:

library(data.table)
setDT(dta, key = c("x", "y"))

dta[.("A", "P"), z]

[1] 89