【问题标题】:How can I speed up this json string cleaning function?如何加快这个 json 字符串清理功能?
【发布时间】:2020-06-01 21:14:05
【问题描述】:

我将国家行政区的替代名称存储在 json 字符串中,并且我具有清理 NA 和重复值的功能;但是,这是一个非常慢的功能,特别是当我在某些数据中有数万行时。我一直在使用整洁的语法,因为我最熟悉它。它有效,但有人对我如何优化此功能有想法吗?

这是一些示例数据和函数:

library(tidyverse)
library(magrittr)
library(rio)
library(jsonlite)
library(tictoc)


data <- import(
  'https://docs.google.com/spreadsheets/d/1Zd_gUj4ejZoTph5i7l_XTRg3pIS2_6tM2mde0SFykzM/edit?usp=sharing',
  setclass = 'tibble'
)

cleanAlternateNames <- function(altNames) {
  tic()
  altNames %<>% lapply(function(x) {
    if (!x %>% is.na()) {
      x %>% fromJSON() %>% plyr::ldply(rbind) %>%
        pivot_longer(-one_of('.id')) %>%
        filter(!is.na(value),!value == 'NA') %>%
        distinct(value, .keep_all = T) %>%
        select(-name) %>%
        pivot_wider(names_from = '.id', values_from = 'value') %>%
        toJSON()
    }
  })
  toc()
  return(altNames)
}

data %<>%
  mutate(AlternateNames = AlternateNames %>% str_replace_all('""','"') %>% 
           cleanAlternateNames)

我修改了示例数据,以提供我想要转换的更好范围。

【问题讨论】:

  • 除非我遗漏了什么,否则您的示例数据都没有两行,因此 rbindpivot_longer 似乎没有必要。也许您可以 1) 提供需要此功能的数据,以及 2) 阐明预期输出的重要方面。
  • 调用 fromjson 时,它会创建一个包含多行的数据框。然后针对 NA 和重复值过滤此数据帧,然后将其转换回 json 字符串。它基本上是将数据帧存储为 json 字符串,尽管字符串的长度不同。
  • 此代码data$AlternateNames %&gt;% str_replace_all('""','"') %&gt;% map(fromJSON) 生成一个长度为99 的列表,其中每个元素都是一个列表,其中包含一个字符向量。
  • 谢谢,这确实很快将其转换为列表。我一直在努力寻找一种方法来过滤列表中的 NA 值和重复项。我更新了原始数据以包含我正在处理的数据的更好样本。
  • 您的编辑大大改变了问题。祝你好运!

标签: r optimization jsonlite


【解决方案1】:

感谢来自Ian Campbell 和另一个用户的有用的 map 使用示例,我能够在我的代码中返回到我最初组合 json 列表的位置,并使用 map 函数删除重复项和重复项。这段代码明显更快,并且无需使用我在之后尝试清理代码的函数。如果有人有类似的问题,我会在这里发布。s

library(tidyverse)
library(magrittr)
library(rio)
library(jsonlite)

# filters out duplicates from first string
.lfilter <- function(x1,x2){
  nm <- names(x1)
  x1 %<>%  unlist
  x1 <- x1[!x1 %in% unlist(x2)] 
  if(length(x1) > 0){
    x1 %<>%
      unname() %>% 
      list() %>% set_names(nm)
  }
  return(x1)
}

# combines two columns that are in json format while removing duplicates
.combineJSONlists <- function(x){
  x %<>% str_split("\\|")
  x1 <- x[[1]][1] %>% fromJSON()
  x2 <- x[[1]][-1] %>% fromJSON() 
  x1 <- map(x1, .lfilter, x2 = x2)
  com <- x1  %>% c(x2) %>% toJSON()
  return(com)
}

# load data
data <- import(
  'https://docs.google.com/spreadsheets/d/1Zd_gUj4ejZoTph5i7l_XTRg3pIS2_6tM2mde0SFykzM/edit?usp=sharing',
  setclass = 'tibble'
)

# combine new and old AlternateNames
data %<>%
  mutate(
    ISO = ISO %>% str_replace_all('""','"'),
    AlternateNames = AlternateNames %>% str_replace_all('""','"') %>% 
      paste0("|",ISO),
    AlternateNames = AlternateNames %>%
      map_chr(.combineJSONlists)) %>% 
  select(-ISO)

【讨论】:

    猜你喜欢
    • 2018-11-17
    • 2011-07-28
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多