我有一个大型数据集,我尝试使用 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)
一图胜千言
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) 显然是赢家。
关于r - 如何使用 dplyr 加速行级操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42344080/