从组dplyr构造字符串

问题描述 投票:3回答:1

我有一个大型数据框,我正在尝试构建一个基于数据框内的组的字符串,以便在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个“级别”和~3000行,处理需要大约30秒,这对于闪亮的应用来说太慢了。

任何帮助将不胜感激。

r shiny dplyr shinytree
1个回答
2
投票

这是一个tidyverse解决方案。关键是使用summarisestr_c(collapse = )将相同的层次结构放在一起,然后mutatestr_c添加额外的list(调用和逗号/空格。包括collapse=意味着字符向量与所需的分隔符一起变成长度为1的字符向量,从而可以与summarise一起使用。我会尝试逐行运行,看看它是如何组合在一起的,交替格式化然后删除层次结构。最后的[[只是为了使它成为一种字符串格式而不是一个tibble。由于实际代码中有更多级别,我将更多重复的str_c调用包装到makelistcollapse函数中,以使其更清晰,更具可读性。

注:额外的好处是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创建于2018-03-01(v0.2.0)。

© www.soinside.com 2019 - 2024. All rights reserved.