【问题标题】:replace specific number of values after a specific occurrence in a vector在向量中特定出现后替换特定数量的值
【发布时间】:2017-01-19 12:20:22
【问题描述】:

玩具模型在这里。该数据代表个人在一年中患上疾病(例如感冒)的天数。该向量是使用每日概率和 rbinom 函数生成的。例如,如果一个人感冒只持续一天,他们可能在感冒后的第二天有额外两天的免疫力,所以我的问题是如何转换这种形式的向量,我在其中再添加两天“对原始寒冷天气的免疫力 (= 1)。

改变这个:

0010001000001001

到这里:

0011101110001111

我查看了 'which' 函数,可以找到原始向量中 1 的索引,但不知道如何将每个 '1' 之后的两个索引替换为 '1'。我还认为我希望新向量的长度与前一个向量相同,即如果接近末尾的值为“1”,则不添加到末尾。

编辑: 我已经设计了这个循环函数,它可以完成这项工作,但我希望有更优雅和高效的解决方案。此外,如果我在原始向量中获得 0,1,1 序列,它将失败。有什么建议吗?

rm(list=ls())
library(zoo)
DayNonSup <- 80
VecLen <- 345
stuff1 <- rep(0,VecLen)
stuff1[c(15,35,335)] <- 1

convert <- function (vector, d) {
    for (i in 1:100) {
        a <-  which(rollapply(vector, 3, identical, c(0,1,0)))[1] + 1
        if(is.na(a)) {break}
        vector[a:(a+d)] <- 1
    }
    vector
}
stuff2 <- convert(stuff1,DayNonSup)[1:VecLen]
stuff2    

【问题讨论】:

    标签: r vector indexing


    【解决方案1】:

    假设您有一个向量,例如下面的s

    s <- unlist(strsplit('0010001000001001', ''))
    s
    [1] "0" "0" "1" "0" "0" "0" "1" "0" "0" "0" "0" "0" "1" "0" "0" "1"
    

    您可以使用dplyr的滞后功能如下:

    s[lag(s) == '1' | lag(s, n = 2) == '1'] <- '1'
    s
    [1] "0" "0" "1" "1" "1" "0" "1" "1" "1" "0" "0" "0" "1" "1" "1" "1"
    

    如果您的值向量是数字 0 / 1,您可以调整此解决方案。只需将'1' 替换为1

    编辑:根据下面的新要求,我建议使用类似的东西。您会发现哪些原始字符串位置有 1。然后,获取除此之外的 80 个索引的列表。缩减整个事情以确保选择的索引保持在原始字符串的长度范围内。使用这些索引中的唯一值替换 1。希望这能满足您的需求。

    index <- unique(unlist(lapply(which(s == '1'),
                           function(x) {
                             index <- x:(x + 80); index <- index[index < length(s)]
                             })))
    s[index] <- '1'
    

    【讨论】:

    • 我可能过于简化了我的示例,并且无法弄清楚如何根据我的需要进行操作。目前我的数组可以有 450 个值,其中只有一个或两个 1。我需要在原始的每个 1 之后添加〜 80 个 1(免疫天数)。有什么建议么?发送
    【解决方案2】:

    如果这是一个字符串,我们可以使用gsub。我们使用正则表达式环视来匹配 1 后跟两个数字 .{2} 并将其替换为两个 1

    gsub("(?<=1).{2}", "11", str1, perl = TRUE)
    #[1] "0011101110001111"
    

    数据

    str1 <- "0010001000001001"
    

    【讨论】:

      【解决方案3】:

      我更喜欢使用向量,而不是存储在字符串中的数据。

      str1 <- '0010001000001001'
      vec <- unlist(strsplit(str1, ''))
      df <- data.frame(day = vec,
                       daymin1 = c(0,vec[1:(length(vec)-1)]),
                       daymin2 = c(0,0,vec[1:(length(vec)-2)]))
      apply(df,1,max)
      

      这是base。另一个答案中提到的dplyr::lag 函数也是一个不错的解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-15
        • 1970-01-01
        • 2015-01-28
        • 1970-01-01
        • 2011-10-07
        相关资源
        最近更新 更多