2014-09-22 49 views
0

我有一個數據集,其中有一列混亂的字符數據。我想將其轉換爲階乘數據進行分析。快速對R中的字符向量進行分類

carData <- data.frame(car=c("Mustang", "Toyota Tercel", "M3", "Datsun 240Z", "Chevy Malibu"), 
       year=c("2001", "1994", "2004", "1980", "2000")) 

      car year 
1  Mustang 2001 
2 Toyota Tercel 1994 
3   M3 2004 
4 Datsun 240Z 1980 
5 Chevy Malibu 2000 

我已經創建了兩個列表來幫助這一點,一個列表搜索字符串,另一個列出相關的類別。

cars <- c("Mustang", "Toyota", "M3", "Chevy") 
make <- c("Ford", "Toyota", "BMW", "Chevrolet") 

我的意圖是循環遍歷列表並在新變量中分配類別。

categorize <- function(df, searchString, category) { 
    df$make <- "OTHER" 
    for(i in seq(1, length(searchString), 1)) { 
    list <- grep(searchString[i], df[,1], ignore.case=TRUE) 
    if (length(list) > 0) { 
     for(j in seq(1, length(list), 1)) { 
     df$make[list[j]] <- category[i] 
     } 
    } 
    } 
    df 
} 

cleanCarData <- categorize(carData, cars, make) 

輸出是:

  car year  make 
1  Mustang 2001  Ford 
2 Toyota Tercel 1994 Toyota 
3   M3 2004  BMW 
4 Datsun 240Z 1980  OTHER 
5 Chevy Malibu 2000 Chevorlet 

我的代碼工作,我的問題是,我的數據有〜1M行,它需要約3個小時才能完成。相反,如果我爲每個語句創建一條語句,則需要不到3分鐘才能完成所有語句。

df$make <- "OTHER" 
df$make[grep("Mustang", df$car, ignore.case=TRUE)] <- "Ford" 
df$make[grep...] 

到目前爲止,我有50個搜索字符串,當我工作通過數據時,我可以很容易地有100個搜索字符串。在可維護的代碼和性能之間是否存在妥協?

+0

會遍歷'cars'和'make'構建'$ DF化妝[...'報表幫助嗎?即對於(我在seq_along(cars))df $ make [grep(cars [i],df $ car,ignore.case = TRUE)] < - make(i)'? – andybega 2014-09-22 16:20:48

+0

您可以將'car'複製到'make'並更改係數級別。 – 2014-09-22 16:22:50

回答

1

你才能把事情通過消除內環更好

categorize <- function(df, searchString, category) { 
    df$make <- "OTHER" 
    for(i in seq_along(searchString)) { 
    list <- grep(searchString[i], df[,1], ignore.case=TRUE) 
    if (length(list) > 0) { 
     df$make[list] <- category[i] 
    } 
    } 
    df 
} 

這是很難實現規模化測試,看看是否that'a其中大部分的時間都花在因爲你的樣本數據不是非常大。

+0

太棒了。這在12秒內對我的整個數據集運行,這比我的50行grep語句快。我從來沒有想過在沒有嵌套循環的情況下嘗試這一點。 – Lenwood 2014-09-22 22:12:17

0

這是一個可能性:

cleanCarData = carData 
for(k in 1:length(cars)) { 
    sel=grep(cars[k], as.character(cleanCarData$car)) 
    cleanCarData[sel,"make"] = make[k] 
} 
cleanCarData$make[is.na(cleanCarData$make)] = "OTHER"