数据框到字典,如 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 创建
您可以使用 setNames
和 Map
获得所需的嵌套列表。
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
我正在尝试创建一个从 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
。
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 创建您可以使用 setNames
和 Map
获得所需的嵌套列表。
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