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