2014-09-22 53 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"