【问题标题】:sapply an ifelse function on character vectors of varying length [r]对不同长度的字符向量应用 ifelse 函数 [r]
【发布时间】:2016-01-24 11:35:24
【问题描述】:

非常感谢您对我的问题的任何帮助,谢谢。

我有一个数据框,其中第二列已经从第一列(在前面的步骤中)提取了“选定”的单词,现在经常(但不总是)将它们留在不同的运行顺序中。我现在需要以与“wordsDF$original”列中相同的运行顺序获取“wordsDF$subbed”列中的单词。

我已经发布了一个小子集,用我手工完成的第四列(wordsDF$target)来说明我的目标。

我正在尝试创建第三列 (wordsDF$reord),这将是使用 sapply() 在 'wordsDF$original' 中找到它们的顺序中的 'wordsDF$subbed' 的单词。我被困在如何将 sapply 函数沿不同长度的 wordsDF$original 字符串的所有单词(即每个字符串中的单词数)传递。我能想到实现这一点的唯一方法是使用 stringr 函数 str_detect 来检测(从左到右)wordsDF$original 中的每个单词是否在 wordsDF$subbed 中,如果“是”将该单词提取到 wordsDF$reord 中(粘贴已提取的任何内容)。如果为“否”,则 wordsDF$reord 列保持不变。

我的解决方案如下,但是,它被硬编码为仅检查和提取第一个单词。谁能告诉我如何沿每个字符串传递函数?还是有更好的方法来重新排序 wordsDF$subbed 并消除对 wordsDF$reord 的需要?

library(stringr)

original = c("heat pump only for 100/150l geyser r410a gas", 
         "alliance allwh 5_dcpt_0kw heat pump only for 200/25",
         "alliance allwinteg 190l integrated heat pump and cylinder r134a gas",
         "aquatouch bt10 cp bottle trap 32x40",
         "aquatouch pop32lux cp slotted pop up basin waste 32mm",
         "aquatouch ci15 cp angle regulating valve only 15x15")

subbed = c("heat pump",
       "heat pump",
       "and cylinder  heat pump",
       "bottle trap",
       "basin  pop up waste",
       "valve")


wordsDF = as.data.frame(cbind(original, subbed))
wordsDF$original = as.character(wordsDF$original)
wordsDF$subbed = as.character(wordsDF$subbed)
wordsDF$reord = character(nrow(wordsDF))
wordsDF$target = c("heat pump","heat pump",
               "heat pump and cylinder",
               "bottle trap","pop up basin waste",
               "valve")

# my attempted solution...
wordsDF$reord = sapply(wordsDF$original, function(x) ifelse(
            test = str_detect(wordsDF$subbed, word(wordsDF$original, 1,1)), 
            yes = paste(wordsDF$reord, str_extract(wordsDF$subbed, word(wordsDF$original, 1,1))),
            no = wordsDF$reord))

提前致谢!

【问题讨论】:

    标签: r sapply stringr


    【解决方案1】:

    这是一个可能的基本 R 解决方案,它在两个拆分向量上运行 mapply,并以正确的顺序返回两者之间的匹配词,并包装到 paste

    Rematch <- function(x, y) paste(y[sort(match(x, y))], collapse = " ") # Define an helper functions
    mapply(Rematch, strsplit(subbed, "\\s+"), strsplit(original, "\\s+"))
    # [1] "heat pump"              "heat pump"              "heat pump and cylinder" "bottle trap"            "pop up basin waste"    
    # [6] "valve"   
    

    【讨论】:

    • 这句话一针见血。非常感谢@David。
    • 您也可以定义Rematch &lt;- function(x, y) paste(x[match(y, x, nomatch = 0)], collapse = " ")。此外,如果总是有一个空格,您可以在两个 strsplit 调用中指定 sep = " "fixed = TRUE 来提高性能(而不是 "\\s+"
    猜你喜欢
    • 2015-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-29
    • 2014-04-15
    • 1970-01-01
    • 2020-12-31
    • 1970-01-01
    相关资源
    最近更新 更多