从组 dplyr 构造字符串
construct string from group dplyr
我有一个大数据框,我正在尝试根据数据框中的组构建一个字符串,以便在 shinyTree 中显示。
这是一个数据示例:
dat <- data.frame("region" = c(paste("region", rep(1:3, each=4))),
"area" = c(paste("area", rep(1:6, each=2))),
"name" = c(paste("name",1:12)))
shinyTree
要求数据在字符串中构造,如下所示:
listString <- paste0("list('region 1' = list('area 1' = list('name 1'='', 'name 2'=''),
'area 2' = list('name 3'='', 'name 4'='')),
'region 2' = list('area 3' = list('name 5'='', 'name 6'=''),
'area 4' = list('name 7'='', 'name 8'='')),
'region 3' = list('area 5' = list('name 9'='', 'name 10'=''),
'area 6' = list('name 11'='', 'name 12'='')))")
有没有办法在 dplyr 中使用 mutate 和 groups 来构造这个字符串? "list("
元素应连接到每个组的第一次出现。
我试过嵌套 for
循环和嵌套 lapply()
函数与 compiler::cmpfun()
来加速它,但事实证明这构建起来太慢了。我的数据有 5 "levels" 和 ~3000 行,处理时间约为 30 秒,这对于闪亮的应用程序来说太慢了。
如有任何帮助,我们将不胜感激。
这是一个tidyverse
解决方案。关键是使用 summarise
和 str_c(collapse = )
将相同的层次结构放在一起,然后 mutate
和 str_c
添加额外的 list(
调用和 commas/spaces.包括 collapse=
意味着字符向量被转换为长度为 1 的字符向量,并带有所需的分隔符,从而可以与 summarise
一起使用。我会逐行尝试 运行 看看它是如何组合在一起的,交替格式化然后删除层次结构。最后的 [[
只是为了使它成为字符串格式而不是小标题。由于实际代码中有更多级别,我将更重复的 str_c
调用包装到 makelist
和 collapse
函数中,以使其更清楚何时发生什么并更具可读性。
N.B。额外的好处是 summarise
删除了旧变量以供使用,并且还删除了分组级别,因此我们不需要任何额外的 group_by
或任何 select
调用!
library(tidyverse)
tbl <- tibble(
"region" = c(paste("region", rep(1:3, each=4))),
"area" = c(paste("area", rep(1:6, each=2))),
"name" = c(paste("name",1:12))
)
makelist <- function(parent, child) str_c("'", parent, "' = list(", child, ")")
collapse <- function(level) str_c(level, collapse = ", ")
tbl %>%
mutate(name = str_c("'", name, "'=''")) %>%
group_by(region, area) %>%
summarise(names = collapse(name)) %>%
mutate(area = makelist(area, names)) %>%
summarise(areas = collapse(area)) %>%
mutate(region = makelist(region, areas)) %>%
summarise(regions = collapse(region)) %>%
mutate(liststr = str_c("list(", regions, ")")) %>%
`[[`(1)
#> [1] "list('region 1' = list('area 1' = list('name 1'='', 'name 2'=''), 'area 2' = list('name 3'='', 'name 4'='')), 'region 2' = list('area 3' = list('name 5'='', 'name 6'=''), 'area 4' = list('name 7'='', 'name 8'='')), 'region 3' = list('area 5' = list('name 9'='', 'name 10'=''), 'area 6' = list('name 11'='', 'name 12'='')))"
由 reprex package (v0.2.0) 创建于 2018-03-01。
我有一个大数据框,我正在尝试根据数据框中的组构建一个字符串,以便在 shinyTree 中显示。
这是一个数据示例:
dat <- data.frame("region" = c(paste("region", rep(1:3, each=4))),
"area" = c(paste("area", rep(1:6, each=2))),
"name" = c(paste("name",1:12)))
shinyTree
要求数据在字符串中构造,如下所示:
listString <- paste0("list('region 1' = list('area 1' = list('name 1'='', 'name 2'=''),
'area 2' = list('name 3'='', 'name 4'='')),
'region 2' = list('area 3' = list('name 5'='', 'name 6'=''),
'area 4' = list('name 7'='', 'name 8'='')),
'region 3' = list('area 5' = list('name 9'='', 'name 10'=''),
'area 6' = list('name 11'='', 'name 12'='')))")
有没有办法在 dplyr 中使用 mutate 和 groups 来构造这个字符串? "list("
元素应连接到每个组的第一次出现。
我试过嵌套 for
循环和嵌套 lapply()
函数与 compiler::cmpfun()
来加速它,但事实证明这构建起来太慢了。我的数据有 5 "levels" 和 ~3000 行,处理时间约为 30 秒,这对于闪亮的应用程序来说太慢了。
如有任何帮助,我们将不胜感激。
这是一个tidyverse
解决方案。关键是使用 summarise
和 str_c(collapse = )
将相同的层次结构放在一起,然后 mutate
和 str_c
添加额外的 list(
调用和 commas/spaces.包括 collapse=
意味着字符向量被转换为长度为 1 的字符向量,并带有所需的分隔符,从而可以与 summarise
一起使用。我会逐行尝试 运行 看看它是如何组合在一起的,交替格式化然后删除层次结构。最后的 [[
只是为了使它成为字符串格式而不是小标题。由于实际代码中有更多级别,我将更重复的 str_c
调用包装到 makelist
和 collapse
函数中,以使其更清楚何时发生什么并更具可读性。
N.B。额外的好处是 summarise
删除了旧变量以供使用,并且还删除了分组级别,因此我们不需要任何额外的 group_by
或任何 select
调用!
library(tidyverse)
tbl <- tibble(
"region" = c(paste("region", rep(1:3, each=4))),
"area" = c(paste("area", rep(1:6, each=2))),
"name" = c(paste("name",1:12))
)
makelist <- function(parent, child) str_c("'", parent, "' = list(", child, ")")
collapse <- function(level) str_c(level, collapse = ", ")
tbl %>%
mutate(name = str_c("'", name, "'=''")) %>%
group_by(region, area) %>%
summarise(names = collapse(name)) %>%
mutate(area = makelist(area, names)) %>%
summarise(areas = collapse(area)) %>%
mutate(region = makelist(region, areas)) %>%
summarise(regions = collapse(region)) %>%
mutate(liststr = str_c("list(", regions, ")")) %>%
`[[`(1)
#> [1] "list('region 1' = list('area 1' = list('name 1'='', 'name 2'=''), 'area 2' = list('name 3'='', 'name 4'='')), 'region 2' = list('area 3' = list('name 5'='', 'name 6'=''), 'area 4' = list('name 7'='', 'name 8'='')), 'region 3' = list('area 5' = list('name 9'='', 'name 10'=''), 'area 6' = list('name 11'='', 'name 12'='')))"
由 reprex package (v0.2.0) 创建于 2018-03-01。