【问题标题】:R split strings in vector with different lengthsR在不同长度的向量中分割字符串
【发布时间】:2017-09-14 10:10:36
【问题描述】:

我在尝试将字符串向量拆分为向量向量时遇到问题。如果有人可以帮助我,请让我卡住。

我有:

V <- c("AAAAA", "AAAAA BBBBB", "CCCCC DDDDD")

使用 strsplit 我得到:

s <- strplit(v)
s
[[1]]
[1] "AAAAA"

[[2]]
[1] "AAAAA" "BBBBB"

[[3]]
[1] "CCCCC" "DDDDD" 

但是我无法访问这些来比较它们。我想要类似的东西:

 s
[1] "AAAAA"
[2] "AAAAA" "BBBBB"
[3] "CCCCC" "DDDDD" 

然后我想看看这些向量中的每一个的元素是否包含在我的验证向量中(如 c("AAAAA", "BBBBB, "CCCCC") 并在最后返回一个布尔值(如果所有元素都为 TRUE在,否则为 FALSE)。 现在我的问题是获取这些向量。欢迎提出任何建议。

【问题讨论】:

    标签: r string split vectorization


    【解决方案1】:

    使用tidyverse,您可以选择

    V <- c("AAAAA", "AAAAA BBBBB", "CCCCC DDDDD")
    validation <- c("AAAAA", "BBBBB", "CCCCC")
    
    library(purrr)
    library(stringr)
    str_split(V, pattern = " ") %>% 
      map_lgl(~all(.x %in% validation))
    #> [1]  TRUE  TRUE FALSE
    

    您也可以将其包含在dplyr 中,以获得关于哪个向量已验证或未验证的清晰摘要。

    library(dplyr, warn.conflicts=F)
    data_frame(V) %>%
      mutate(validate = str_split(V, pattern = " ") %>% 
               map_lgl(~all(.x %in% validation)))
    #> # A tibble: 3 x 2
    #>             V validate
    #>         <chr>    <lgl>
    #> 1       AAAAA     TRUE
    #> 2 AAAAA BBBBB     TRUE
    #> 3 CCCCC DDDDD    FALSE
    

    【讨论】:

    • 非常感谢,确实有效!我不熟悉您使用的所有软件包,但我一定会加快速度!
    【解决方案2】:

    strsplit 返回一个列表,您可以通过自定义函数使用 lapply 来处理它

    V <- c("AAAAA", "AAAAA BBBBB", "CCCCC DDDDD")
    s <- strsplit(V, split = " ")
    val <- c("AAAAA", "BBBBB", "CCCCC")
    
    lapply(s, function(x) x %in% val)
    

    您可以像这样访问列表元素:

    s[[1]]
    s[[2]]
    

    检查 val 中是否存在所有元素

    all <- lapply(s, function(x) sum(x %in% val) == length(val))
    #output 
    [[1]]
    [1] FALSE
    
    [[2]]
    [1] FALSE
    
    [[3]]
    [1] FALSE
    

    将此列表转换为向量

    all <- unlist(all)
    

    从 V 返回原始元素

    v[all]
    

    【讨论】:

    • 感谢您的意见。我曾认为这是我的问题,然后是访问最终结果。就像从 c(FALSE, TRUE, FALSE) 中获取一些东西并处理缺失值一样。
    【解决方案3】:

    R 没有向量的向量。

    要模拟这种行为,您通常会使用lists 和apply-family。


    input_vector <- c("AAAAA", "AAAAA BBBBB", "CCCCC DDDDD")
    
    # split the string like you did
    s <- strsplit(input_vector, split = " ")
    s
    #> [[1]]
    #> [1] "AAAAA"
    #> 
    #> [[2]]
    #> [1] "AAAAA" "BBBBB"
    #> 
    #> [[3]]
    #> [1] "CCCCC" "DDDDD"
    
    # create a vector with conditions that wee look for
    validation_vector <- c("AAAAA", "BBBBB")
    
    # create a matrix of matches
    res_matrix <- sapply(s, function(s_part) {
      validation_vector %in% s_part
    })
    
    # check if all validation_vector elements are true for a given input_vector-string
    # by applying the 'all'-function over each column ("are all elements for a given column TRUE?")
    res_vector <- apply(res_matrix, 2, all)
    # for aesthetic purposes: add the name of the initial input_vector again
    names(res_vector) <- input_vector
    
    # display the result
    res_vector
    #>       AAAAA AAAAA BBBBB CCCCC DDDDD 
    #>       FALSE        TRUE       FALSE
    

    【讨论】:

      【解决方案4】:

      您可以查看*apply 系列函数。例如,使用sapply 将strsplit 函数应用于您获得的每个列表元素

      vs <- sapply(V, strsplit, split = " ")
      
      vs
      
      $AAAAA
      [1] "AAAAA"
      
      $`AAAAA BBBBB`
      [1] "AAAAA" "BBBBB"
      
      $`CCCCC DDDDD`
      [1] "CCCCC" "DDDDD"
      

      进一步检查validation你可以做的向量

      validation <- c("AAAAA", "BBBBB", "CCCCC")
      vs_in_val <- sapply(vs, `%in%`, validation) 
      
      vs_in_val
      
      $AAAAA
      [1] TRUE
      
      $`AAAAA BBBBB`
      [1] TRUE TRUE
      
      $`CCCCC DDDDD`
      [1]  TRUE FALSE
      

      【讨论】:

      • 谢谢。我尝试广泛应用,但最终如果失败了。我基本上想避免那个列表元素。
      【解决方案5】:

      如果你将它与“lapply”结合使用,strsplit 可以帮助你做到这一点。

      V <- c("AAAAA", "AAAAA BBBBB", "CCCCC DDDDD")
      s <- strsplit(V," ")
      sapply(s,function(x) return (sum(x %in% c("AAAAA", "BBBBB", "CCCCC"))/length(x)))
      [1] 1.0 1.0 0.5
      

      如果结果返回 0,则表明验证向量中没有元素。

      如果为 1,则验证向量中的所有元素。

      如果介于 0 和 1 之间,则验证向量中有一些元素。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-01-06
        • 2014-07-29
        • 2020-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-01
        相关资源
        最近更新 更多