【问题标题】:R strsplit and filtering based on sub-indices matching in the logical vectors基于逻辑向量中匹配的子索引的 R strsplit 和过滤
【发布时间】:2018-04-27 08:39:31
【问题描述】:

我想以这样一种方式应用 strsplit,如果存在一对相同的值与 &(例如,这是一对与 & (NINA & SAM)),也与 | (例如,这是另一对,但带有 | (NINA | SAM))然后保留带有 & 的一对

以下是 2 种可能的情况,这些向量 (vec1, vec2) 的长度可能因实际情况而异。

案例一

> vec1
[1] "((PAUL & SAM) | (PAUL | SAM) | (NINA & SAM) | (NINA | SAM) | (NINA & PAUL) | (NINA | PAUL))"
> vec2
[1] "((PAUL | SAM) & (PAUL & SAM) & (NINA | SAM) & (NINA | PAUL) & (NINA & PAUL) & (NINA & SAM))"

案例 2

> vec1
[1] "((PAUL | SAM) | (PAUL & SAM) | (!NINA & SAM) | (!NINA & PAUL))"
> vec2
[1] "((PAUL | SAM) & (PAUL & SAM) & (!NINA & SAM) & (!NINA & PAUL))"

这应该是输出:

案例一

> vec1
[1] "((PAUL & SAM) | (NINA & SAM) | (NINA & PAUL))"
> vec2
[1] "((PAUL & SAM) & (NINA & PAUL) & (NINA & SAM))"

案例 2

> vec1
[1] "((PAUL & SAM) | (!NINA & SAM) | (!NINA & PAUL))"
> vec2
[1] "((PAUL & SAM) & (!NINA & SAM) & (!NINA & PAUL))"

到目前为止我所尝试的:

我的想法是首先从向量的开头和结尾删除 (()),然后将 vec1 拆分为 ") | (" ,将 vec2 拆分为 ") & (" 。然后进一步拆分space*space 上的索引并检查子索引1 和2 是否与任何其他子索引匹配,如果是,则保留具有& 的索引。然后把所有东西放回去。我对 R 的了解有限,无法实现我的想法。任何帮助将不胜感激!

【问题讨论】:

    标签: r strsplit


    【解决方案1】:

    我相信以下内容可以满足您的要求。
    它不是很漂亮,但输出是正确的。

    keepAmpersand <- function(x) {
        y <- sub("\\(\\(", "(", x)  # get rid of the double
        y <- sub("\\)\\)", ")", y)  # parenthesis
        # this regex is meant to replace either a '|' or a '&'
    
        # with the same character between '#' (one '#' on each side)  
        y <- gsub("(\\) \\| \\(|\\) & \\()", ")#\\1#(", y)
    
        # now use that special pattern, '# five chars #' to split
        y <- unlist(strsplit(y, "#.{5}#"))
    
        # keep the ones with the ampersand or with just one name
        y <- grep("&|\\([[:alpha:]]+\\)", y, value = TRUE)
        y <- paste0("(", paste(y, collapse = " | "), ")")    # reassemble
        y
    }
    

    现在将函数应用于每个案例。

    案例一

    vec1 <-
    "((PAUL & SAM) | (PAUL | SAM) | (NINA & SAM) | (NINA | SAM) | (NINA & PAUL) | (NINA | PAUL))"
    vec2 <-
    "((PAUL | SAM) & (PAUL & SAM) & (NINA | SAM) & (NINA | PAUL) & (NINA & PAUL) & (NINA & SAM))"
    
    
    keepAmpersand(vec1)
    #[1] "((PAUL & SAM) | (NINA & SAM) | (NINA & PAUL))"
    
    keepAmpersand(vec2)
    #[1] "((PAUL & SAM) | (NINA & PAUL) | (NINA & SAM))"
    

    案例 2

    vec1 <-
    "((PAUL | SAM) | (PAUL & SAM) | (!NINA & SAM) | (!NINA & PAUL))"
    vec2 <- 
    "((PAUL | SAM) & (PAUL & SAM) & (!NINA & SAM) & (!NINA & PAUL))"
    
    
    keepAmpersand(vec1)
    #[1] "((PAUL & SAM) | (!NINA & SAM) | (!NINA & PAUL))"
    
    keepAmpersand(vec2)
    #[1] "((PAUL & SAM) | (!NINA & SAM) | (!NINA & PAUL))"
    

    情况 3:括号之间只有一个名字的情况。

    vec3 <-
    "((PAUL | SAM) & (PAUL & SAM) & (NINA | SAM) & (NINA | PAUL) & (NINA & PAUL) & (NINA))"
    
    keepAmpersand(vec3)
    #[1] "((PAUL & SAM) | (NINA & PAUL) | (NINA))"
    

    【讨论】:

    • 非常感谢您抽出时间来帮助我。最终输出缺少括号之间的链接,例如对于 Case2 vec1"(PAUL &amp; SAM)" "(!NINA &amp; SAM)" 应该是 "(PAUL &amp; SAM)" | "(!NINA &amp; SAM)"。其次,额外的开始和结束括号也不见了。您能否评论代码,以便我可以轻松理解每一行在做什么。再次感谢!
    • @Newbie 看看是不是这个。请注意,它只是"(PAUL &amp; SAM) | (!NINA &amp; SAM)",在条形| 附近没有引号。
    • 感谢您的帮助。只是一件小事是它在括号只有一个名称的情况下不起作用,例如"((PAUL | SAM) &amp; (PAUL &amp; SAM) &amp; (NINA | SAM) &amp; (NINA | PAUL) &amp; (NINA &amp; PAUL) &amp; (NINA))" 在这种情况下,它不会报告最后一个 (NINA) 。很抱歉我没有在输入数据样本中设置这样的约束,但实际上我确实有这样的输入。
    • 很抱歉给您带来不便,但在 Case3 中 (NINA | SAM) 已退出,但原本不应该退出。因为没有其他索引具有这些名称。你能解释一下吗。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2014-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-20
    • 2021-12-20
    • 2021-10-01
    • 1970-01-01
    相关资源
    最近更新 更多