【问题标题】:construct string from group dplyr从组 dplyr 构造字符串
【发布时间】:2018-02-28 11:03:42
【问题描述】:

我有一个大数据框,我正在尝试根据数据框中的组构造一个字符串,以便在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】:

    这是一个tidyverse 解决方案。关键是使用summarisestr_c(collapse = ) 将相同的层次结构放在一起,然后使用mutatestr_c 添加额外的list( 调用和逗号/空格。包含collapse= 意味着将字符向量转换为具有所需分隔符的长度为一的向量,从而可以与summarise 一起使用。我会尝试逐行运行以查看它是如何组合在一起的,交替格式化然后删除层次结构。最后的[[ 只是为了使其成为字符串格式而不是小标题。由于实际代码中存在更多级别,因此我将更多重复的 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 (v0.2.0) 于 2018 年 3 月 1 日创建。

    【讨论】:

    • 这很棒,它将构建时间从约 30 秒减少到 0.13 秒!非常感谢。
    猜你喜欢
    • 2013-02-04
    • 2019-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-16
    • 1970-01-01
    • 2014-12-02
    • 1970-01-01
    相关资源
    最近更新 更多