如何使用dplyr
加快行级操作我有一个大的数据集,我尝试使用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
我从一个非有效的角度来解决这个问题。使用矢量化方法可以明显改善性能。
为了完整起见,我运行整个数据集的随机微小的子集的代码,以评估性能和清晰矢量是去我的问题的方式。
最后提到,需要预清洗任务,以确保所产生的变换数字(指大卫的意见,了解详细信息)是非常重要的
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)
一张图片胜过千言万语
从大卫另一个建议是后,将数据转换成数字。我添加了两个函数,一个是在整个列上进行转换,另一个是在分割后应用类型转换。
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)显然是赢家。
我认为明确地将'latitude'和'longitude'转换为'tstrsplit'内的'type.convert = TRUE'后的数值可能会使速度加倍。 –
谢谢@DavidArenburg - 我根据你的建议详细阐述了这个例子。 – Michael
首先我们没有MWE,所以我们不能真正帮助你。其次,通过查看你的代码,我怀疑你需要按行运行'strsplit'。你可能很容易用'data.table :: tstrsplit'完成整个事情。第三,如果你想快速分割,不要使用正则表达式,也不要每行运行'as.charcter'(每次两次!)。即''VR_vehicle_GPSLocation''应该已经是一个字符,然后再开始做一些东西,而不是''\\ |''''''''与'fixed = TRUE'结合使用。但是在那里,我们需要一个MWE。 –
谢谢@DavidArenburg我正在忙于创建一个示例,所以它会更有意义。 – Michael
'library(data.table); setDT(df)[grep(“|”,VR_vehicle_GPSLocation,fixed = TRUE),c(“纬度”,“经度”):= tstrsplit(VR_vehicle_GPSLocation,“|”,fixed = TRUE,keep = 1:2,type。转换= TRUE)]'和你很好去。 –