我的数据框超过一百万行。它有一个键值,键值为字符。该关键列有大约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系统上完成。
如何使此映射以尽可能最快的方式执行?非常感谢你的帮助。
答案 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真是太棒了。需要探索并更多地使用它。感谢。