R数据帧中基于正则表达式的字符串重映射
我试图通过循环其他数据帧中定义的正则表达式来清除某些数据帧中混乱的自由形式捕获字符串。例如:R数据帧中基于正则表达式的字符串重映射,r,dataframe,vectorization,R,Dataframe,Vectorization,我试图通过循环其他数据帧中定义的正则表达式来清除某些数据帧中混乱的自由形式捕获字符串。例如: id <- c(1, 2, 3, 4) text <- c(NA, "messy1 messy2", "MESSY2,,, messy1", "ignore") df <- data.frame(id, text) mapin <- c("messy1", "messy2") mapout <- c("Clean 1", "Clean 2") map <- dat
id <- c(1, 2, 3, 4)
text <- c(NA, "messy1 messy2", "MESSY2,,, messy1", "ignore")
df <- data.frame(id, text)
mapin <- c("messy1", "messy2")
mapout <- c("Clean 1", "Clean 2")
map <- data.frame(mapin, mapout)
cout <- c(NA, "Clean 1, Clean 2", "Clean 1, Clean 2", NA)
id使用stri\u extract\u all
从stringi
包中提取:
library(stringi)
m1 <- sapply(map$mapin, function(x) stri_extract_all_fixed(tolower(df$text), x))
m2 <- matrix(map$mapout[match(m1, map$mapin)], ncol = nrow(map))
vec <- apply(m2, 1, function(x) paste(na.omit(x), collapse = ", ") )
vec[vec == ''] <- NA
df$cout <- vec
库(stringi)
m1基于@Jaap的伟大答案,在我的问题域中出现了一些调整,但这可能是其他人面临的常见挑战:
创建矩阵m2
时动态确定贴图的大小
对输出标记进行一致的排序
使用stri\u extract\u first\u fixed
对重复的输入令牌不敏感
完整示例:
# Problem
id <- c(1, 2, 3, 4)
text <- c(NA, "messy1 messy2", "MESSY2,,, messy1,messy1", "ignore")
df <- data.frame(id, text)
mapin <- c("messy2", "messy1")
mapout <- c("Clean 2", "Clean 1")
map <- data.frame(mapin, mapout)
# Solution
m1 <- sapply(map$mapin, function(x) stri_extract_first_fixed(tolower(df$text), x))
m2 <- matrix(map$mapout[match(m1, map$mapin)], ncol = nrow(map))
vec <- apply(m2, 1, function(x)
paste0(c(unique(sort(x, na.last = NA)), use.names = FALSE), collapse = ", "))
vec[vec==''] <- NA
df$clean <- vec
#问题
id您的输出令牌中是否包含空格?不太清楚这些应该如何排序。您不一定需要正则表达式,因为您的示例都是固定文本。您是否尝试过使用gsub
进行迭代?此外,您的cout
还意味着其他清理/标准化操作,例如添加或单个逗号。@David:是的,有些是,有些不是。不过,在本例中,我实际上是在对输出的一致性进行排序(因此,同一组输入标记将生成同一组输出标记,而不考虑顺序)。所以,只是为了让人类的评审人员更容易理解set1==set2。@r2evans:在这个例子中,正则表达式的复杂性确实不多;我在这里回答这个问题。我曾研究过使用gsub进行迭代,但由于我这里的问题有一半是用户在面对自由格式文本时键入的内容千差万别的“谷壳中的小麦”,因此从长远来看,只提取有效标记似乎比尝试就地替换更容易。因为,事实上,这会让我有其他的清洁/标准化工作要做。斯特林尼:你这辈子都到哪里去了!?谢谢你,雅普!
# Problem
id <- c(1, 2, 3, 4)
text <- c(NA, "messy1 messy2", "MESSY2,,, messy1,messy1", "ignore")
df <- data.frame(id, text)
mapin <- c("messy2", "messy1")
mapout <- c("Clean 2", "Clean 1")
map <- data.frame(mapin, mapout)
# Solution
m1 <- sapply(map$mapin, function(x) stri_extract_first_fixed(tolower(df$text), x))
m2 <- matrix(map$mapout[match(m1, map$mapin)], ncol = nrow(map))
vec <- apply(m2, 1, function(x)
paste0(c(unique(sort(x, na.last = NA)), use.names = FALSE), collapse = ", "))
vec[vec==''] <- NA
df$clean <- vec