代码之家  ›  专栏  ›  技术社区  ›  Andre Elrico

从模式的第一次出现到结束设置值NA

r
  •  2
  • Andre Elrico  · 技术社区  · 6 年前

    是否有一种更快/更短的方法来设置匹配到NA之后的值(包括匹配到NA之后的值)?

    vec <- 1:10;vec[c(3,5,7)]<-c(NA,NaN,"remove")
    #"1"      "2"      NA       "4"      "NaN"    "6"      "remove" "8"      "9"      "10"    
    

    预期结果:

    #"1"      "2"      NA       "4"      "NaN"    "6"      NA       NA       NA       NA
    

    我的代码:

    vec[{grep("^remove$",vec)[1]}:length(vec)]<-NA
    

    在这种情况下,我们假设会有一个突出的“remove”元素。所以解决方案不必考虑没有的情况。

    4 回复  |  直到 6 年前
        1
  •  3
  •   Frank    6 年前

    你可以用 match 要在找到第一个匹配项后停止搜索:

    m = match("remove", vec) - 1L
    if (is.na(m)){
      vec 
    } else {
      c(head(vec, m), rep(vec[NA_integer_], length(vec)-m))
    }
    

    不过,我想你得有一个很大的矢量才能注意到速度差。或者,这可能会更快:

    m = match("remove", vec)
    if (!is.na(m)){
      vec[m:length(vec)] <- NA 
    }
    
        2
  •  3
  •   Ronak Shah    6 年前

    不确定这是短还是快,但有一个选择:

    vec[which.max(vec == "remove"):length(vec)] <- NA
    vec
    #[1] "1"   "2"   NA    "4"   "NaN" "6"   NA    NA    NA    NA   
    

    在这里,我们发现第一次出现“remove”时使用 which.max 然后添加 NA 一直到矢量的末尾。


    OP提到总是有一个“remove”元素,所以我们不需要处理其他情况,但是,如果我们仍然想保持一个检查,我们可以添加一个附加条件。

    inds <- vec == "remove"
    if (any(inds)) {
      vec[which.max(inds) : length(vec)] <- NA
    }
    
        3
  •  2
  •   akrun    6 年前

    我们可以利用 cumsum 关于逻辑向量

    vec[cumsum(vec %in% "remove") > 0] <- NA
    
        4
  •  0
  •   Onyambu    6 年前

    我们也可以将vec扩展到所需的长度:

    `length<-`(vec[1:(which(vec=="remove")-1)],length(vec))
     [1] "1"   "2"   NA    "4"   "NaN" "6"   NA    NA    NA    NA