增强数据帧列转换代码的执行时间

时间:2014-05-16 18:43:32

标签: r

我的数据框超过一百万行。它有一个键值,键值为字符。该关键列有大约900个不同的值。许多这些值是标准值的微小变化。在这900个值中,大约175个值将映射到标准值。以下示例代码说明了如何完成映射以更正值。这里“事件1”值需要用“evt 1”代替:

id = c(1:4)
k1 = c("Event 1", "evt 1", "evt 2", "evt 3")
v1 = c(101:104)
df = data.frame(id, k1, v1)
df$k1 = as.character(df$k1)

### map the non-standard values to standard values using named vector approach
mapEvents = c("Event 1" = "evt 1")
vNames = names(mapEvents)

stTime = proc.time()
df$k1 = ifelse(df$k1 %in% vNames, mapEvents[df$k1], df$k1)
proc.time() - stTime

此代码工作正常,但存在严重的性能问题。 ifelse代码大约需要9分钟才能在我的i7系统上完成。

如何使此映射以尽可能最快的方式执行?非常感谢你的帮助。

3 个答案:

答案 0 :(得分:2)

如果只是'你希望做的更换来自" Event" to" evt",但是对于具有不同序列号的大量组合,仅替换字符串可能更方便。如果不了解您的数据,那么很难说清楚。

library(stringi)
stri_replace_first_fixed(str = k1, pattern = "Event", replacement = "evt")
# [1] "evt 1" "evt 1" "evt 2" "evt 2" "evt 3" "evt 3"

答案 1 :(得分:0)

df$k1[df$k1 %in% "Event 1"] <- "evt 1"

如果您有多个值,则需要重新映射:

remap <- list("evt 1" = "Event 1",
              "evt 2" = c('a','b','c'),
              "evt 3" = c('x','y','z'),
              ...etc...)

for(i in seq_along(remap)) {
    w <- which(df$k1 %in% remap[[i]])
    df$k1[w] <- names(remap)[i]
}

答案 2 :(得分:0)

基于SO问题Update subset of data.table based on join,以下是一个答案。

## convert the mapping vector to a data table
  dtMap = data.table(idMap=names(mapEvents), mappedValue=mapEvents)
  setkey(dtMap, idMap)

  ## convert the data frame to a data table
  dt_df = data.table(df)
  setkey(dt_df, k1)

  ## do the update and convert the data table back to data frame
  dt_df[dtMap[dt_df[k1 %in% dtMap$idMap],nomatch=0],c("k1"):=list(i.mappedValue)]
  df = as.data.frame(dt_df)

data.table真是太棒了。需要探索并更多地使用它。感谢。