2017-02-20 127 views
2

加快行級操作我有一個大的數據集,我嘗試使用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() 
+1

首先我們沒有MWE,所以我們不能真正幫助你。其次,通過查看你的代碼,我懷疑你需要按行運行'strsplit'。你可能很容易用'data.table :: tstrsplit'完成整個事情。第三,如果你想快速分割,不要使用正則表達式,也不要每行運行'as.charcter'(每次兩次!)。即''VR_vehicle_GPSLocation''應該已經是一個字符,然後再開始做一些東西,而不是''\\ |''''''''與'fixed = TRUE'結合使用。但是在那裏,我們需要一個MWE。 –

+0

謝謝@DavidArenburg我正在忙於創建一個示例,所以它會更有意義。 – Michael

+1

'library(data.table); setDT(df)[grep(「|」,VR_vehicle_GPSLocation,fixed = TRUE),c(「緯度」,「經度」):= tstrsplit(VR_vehicle_GPSLocation,「|」,fixed = TRUE,keep = 1:2,type。轉換= TRUE)]'和你很好去。 –

回答

2

所有信貸@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) 

一張圖片勝過千言萬語

enter image description here


從大衛另一個建議是後,將數據轉換成數字。我添加了兩個函數,一個是在整個列上進行轉換,另一個是在分割後應用類型轉換。

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

+1

我認爲明確地將'latitude'和'longitude'轉換爲'tstrsplit'內的'type.convert = TRUE'後的數值可能會使速度加倍。 –

+0

謝謝@DavidArenburg - 我根據你的建議詳細闡述了這個例子。 – Michael