r - 如何使用 dplyr 加速行级操作

标签 r dplyr

我有一个大型数据集,我尝试使用 dplyr 对其进行操作。我的数据整理任务需要行级字符串操作。

我正在使用默认的 rowwise() 函数,代码可以正常工作。但是,该操作需要很长时间才能完成。

VR_vehicle_GPSLocation = c("12.36556|0.74518153|xxxxxxxxxx", 
      "-51.75810|165.55526|xxxxxxxxxx", 
      "GPS nicht verfügbar",
      "48.77410|171.08364|xxxxxxxxxx", 
      "GPS Not Available",
      "0|0|N/R",
      "32.18661| 170.56615|xxxxxxxxxx")
df = data.frame(VR_vehicle_GPSLocation)

jobs_location <- df %>%
     rowwise() %>% 
     mutate(latitude  = as.numeric(unlist(strsplit(as.character(VR_vehicle_GPSLocation), split='\\|'))[1]),
            longitude = as.numeric(unlist(strsplit(as.character(VR_vehicle_GPSLocation), split='\\|'))[2])) %>%
     select(latitude, longitude)

为了加快这个过程,我探索了 multidyplyr 库但没有成功,我收到一条错误消息,说我的数据集不是数据框。

jobs_location <- jobs %>%
  partition() %>%
  rowwise() %>% 
  mutate(latitude  = as.numeric(unlist(strsplit(as.character(VR_vehicle_GPSLocation), split='\\|'))[1]),
         longitude = as.numeric(unlist(strsplit(as.character(VR_vehicle_GPSLocation), split='\\|'))[2])) %>%
  collect()

最佳答案

所有归功于@DavidArenburg

我从一个非高效的角度来处理这个问题。使用矢量化方法可以明显提高性能。

为了完整起见,我在整个数据集的一个随机小子集上运行代码以评估性能,显然矢量化是解决我的问题的方法。

最后重要的是要提到需要进行预清理任务以确保生成的转换是数字的(有关更多详细信息,请参阅 David 的评论)

library(dplyr)
library(data.table)
library(microbenchmark)
library(ggplot2)

mbm = microbenchmark(
  a = sample_n(jobs, 100) %>%
    rowwise() %>% 
    mutate(latitude  = as.numeric(unlist(strsplit(as.character(VR_vehicle_GPSLocation), split='\\|'))[1]),
           longitude = as.numeric(unlist(strsplit(as.character(VR_vehicle_GPSLocation), split='\\|'))[2])),

  b = setDT(sample_n(jobs, 100))[grep("|", VR_vehicle_GPSLocation, fixed = TRUE), 
                   c("latitude", "longitude") := tstrsplit(VR_vehicle_GPSLocation, "|", fixed = TRUE, keep = 1:2, type.convert = TRUE)]
)

autoplot(mbm)

一图胜千言

enter image description here


David 的另一个建议是在tstrsplit 之后将数据转换为数字。我添加了两个函数,一个是对整个列进行转换,另一个是在拆分后应用类型转换。

mbm = microbenchmark(
  a = sample_n(jobs, 100) %>%
    rowwise() %>% 
    mutate(latitude  = as.numeric(unlist(strsplit(as.character(VR_vehicle_GPSLocation), split='\\|'))[1]),
           longitude = as.numeric(unlist(strsplit(as.character(VR_vehicle_GPSLocation), split='\\|'))[2])),

  b = setDT(sample_n(jobs, 100))[grep("|", VR_vehicle_GPSLocation, fixed = TRUE), 
                                 c("latitude", "longitude") := tstrsplit(VR_vehicle_GPSLocation, "|", fixed = TRUE, keep = 1:2, type.convert = TRUE)],

  c = sapply(setDT(sample_n(jobs, 100))[grep("|", VR_vehicle_GPSLocation, fixed = TRUE), 
                                 c("latitude", "longitude") := tstrsplit(VR_vehicle_GPSLocation, "|", fixed = TRUE, keep = 1:2)], as.numeric),

  d = setDT(sample_n(jobs, 100))[grep("|", VR_vehicle_GPSLocation, fixed = TRUE), 
                                        c("latitude", "longitude") := lapply(tstrsplit(VR_vehicle_GPSLocation, "|", fixed = TRUE, keep = 1:2), as.numeric)]
)
autoplot(mbm)

最后一个变体 (d) 显然是赢家。

enter image description here

关于r - 如何使用 dplyr 加速行级操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42344080/

相关文章:

r - 在 R 中使用 React JS 抓取网页

r - 如何 reshape 宽汇总表?

r - dplyr 在变量子集上使用 pivot_longer 和 pivot_wider

运行 `.x` 函数后用列名替换 `map::purrr()`

r - 如何用NA替换空白字符串?

r - 乘以概率分布函数

r - 为什么我的用于过滤数据的 R 代码会产生不同的结果 "fread()"和 "ffdf()"?

r - 使用 OpenMP 编译 CRAN 二进制文件需要哪些 Hook ? (在 OS X 上)

r - 使用 gtools::mixedsort 或 dplyr::arrange 的替代品

r - 从gather()到pivot_longer()的数据集转换