【问题标题】:Extract character from string based on character in another vector in R基于R中另一个向量中的字符从字符串中提取字符
【发布时间】:2018-04-03 21:37:14
【问题描述】:

我是社区的新手,希望我的问题和示例符合标准。

我有一个包含两个字符向量的数据框。向量 a 中的值长度不同,向量 b 中的值都只包含一个字符。

a <- as.character(c("tsm", "skr", "fl", "pfl", "ts", "St", "S"))
b <- as.character(c("m", "k", "l", "l", "s", "t", "S"))
uedf <- data.frame(a, b)

我想直接提取向量 b 中指定的字符左侧的字符。该字符在字符串中的位置可能会有所不同。因此,我想从第一个字符串中提取“s”(m 的左侧),在第二个字符串中再次提取“s”(k 的左侧)等等。

由于我不知道如何使用grepl()(我对正则表达式不是很熟悉)来做到这一点,我最终得到了strsplit()str_sub() 的组合。

str_sub(strsplit(uedf$a,split=uedf$b, fixed=FALSE), start = -1, end = -1)

这适用于大多数情况,除了第二个它返回“)”而不是所需的“s”。

[1] "s" ")" "f" "f" "t" "S" "" 

任何想法为什么会这样以及我如何解决这个问题? 提前致谢!

【问题讨论】:

    标签: r string


    【解决方案1】:

    我认为str_sub 仅适用于字符串,但对于第二个字符串strsplit 为您提供了一个包含 2 个字符串的向量。

    如果分隔符在每个字符串中只出现一次,这将完成这项工作:

    sapply(strsplit(a,split=b, fixed=FALSE), function(l) str_sub(l[[1]],-1,-1))
    

    【讨论】:

    • 啊,这就是我在使用第二个字符串时遇到问题的原因。谢谢!但是您的解决方案似乎返回了 b 指定的字符之前的所有字符,而不仅仅是与其相邻的字符。
    • 我更正了它,使它只返回字符串中的最后一个字符,后跟分隔符
    【解决方案2】:

    这是使用base R的gsub的解决方案:

    sapply(1:length(a), function(i) ifelse(
        nchar(a[i]) > 1,
        gsub(paste0("^.*(\\w)", b[i], ".*$"), "\\1", a[i]),
        ""))
    #[1] "s" "s" "f" "f" "t" "S" ""
    

    或者使用mapply 更加简洁和干净/整洁(感谢@thelatemail):

    mapply(function(a,b) ifelse(
        nchar(a) > 1, 
        gsub(paste0("^.*(\\w)", b, ".*$"), "\\1", a), 
        ""), a, b)
    

    【讨论】:

    • 成功了,非常感谢!只是为了澄清:“\\1”是告诉R只返回一个字符的部分吗?
    • @sakwa 一般"\\1"返回第1组捕获的表达式,本例为(\\w),对应一个字符。
    • @MauritsEvers - 去吧。
    • @MauritsEvers:感谢您的解释!还有mapply 解决方案(也是@thelatemail)!
    【解决方案3】:

    我在这里找到与您的索引匹配的位置并将它们保存在i 中。然后提取字符比i 少一个。

    i <- mapply(regexpr, b, a) - 1
    substr(a, i, i)
    [1] "s" "s" "f" "f" "t" "S" "" 
    

    【讨论】:

    • 类似的逻辑是strsplitmatch,然后substr以同样的方式:n &lt;- mapply(match, b, strsplit(a,"")) - 1; substr(a, n, n)。同样,您也可以将您的sapply 行重写为mapply(regexpr, b, a)
    • 非常有趣的解决方案!非常感谢!
    • @thelatemail 不错!我经常忘记利用 mapply 的力量。
    猜你喜欢
    • 2022-01-17
    • 2019-01-14
    • 1970-01-01
    • 1970-01-01
    • 2015-05-21
    • 1970-01-01
    • 2017-02-19
    • 2018-02-05
    • 1970-01-01
    相关资源
    最近更新 更多