【问题标题】:Identify runs in R, allowing for gaps识别 R 中的运行,允许间隙
【发布时间】:2018-03-25 15:53:16
【问题描述】:

我已经使用此处的帮助板来识别 R 中的运行。例如:

temp.data = rle(c(NA, NA, 1, NA, NA, 1, NA, 1, 1, 1, NA, NA, NA))
output = temp.data$lengths[temp.data$value==1] 

这里,“输出”返回以下内容:

NA NA  1 NA NA  1 NA  3 NA NA NA

这行得通,告诉我有 1、1 和 3 次运行。但是,除了我上面所做的之外,我还想确定具有某种程度的“宽恕”的运行。例如,如果 1 表示事件发生,而 NA 表示事件未发生,我希望允许有 1 的间隙。因此,我希望我的输出为:

NA NA 1 NA NA 5 NA NA NA

或者,它可以简单地返回有 1 和 5 的运行。我正在尝试在具有几列和数百行的数据框中执行此操作,每个单元格都是 1 和 NA 的列表,因此我会喜欢自动化这个过程。谢谢!

【问题讨论】:

  • 你想用 1 替换前导和尾随单个 NAs 吗?比如x1 = c(NA, 1, NA, 1, 1, NA)
  • 不,但后来我意识到我没有澄清这一点。您的原始答案效果很好。

标签: r run-length-encoding


【解决方案1】:

创建NA 的运行长度,将长度为1 的NA 运行替换为FALSE。然后替换由!inverse.rle(r)索引的x的值:

r <- rle(is.na(x))
r$values[r$values][r$lengths[r$values] == 1] <- FALSE
x[!inverse.rle(r)] <- 1
x
# [1] NA NA  1 NA NA  1  1  1  1  1 NA NA NA

如果您不介意使用非basezoo::na.approx 及其maxgap 参数是一个方便的包装器:

na.approx(x, maxgap = 1, na.rm = FALSE)
# [1] NA NA  1 NA NA  1  1  1  1  1 NA NA NA

na.approx 也可以输入数据框:

d <- data.frame(x1 = c(NA, 1, NA, 1, 1, NA),
                x2 = c(1, NA, 1, NA, NA, 1))

na.approx(d, maxgap = 1, na.rm = FALSE)
#      x1 x2
# [1,] NA  1
# [2,]  1  1
# [3,]  1  1
# [4,]  1 NA
# [5,]  1 NA
# [6,] NA  1 

如果您的数据集很大,您可以使用“长”格式的data.table

library(data.table)
setDT(d)

# convert to long format
d2 <- melt(d, measure.var = names(d))

# for each variable and run, add group number and group length
d2[ , `:=`(g = .GRP, n = .N), by = .(variable, rleid(value))]

# for each variable, replace runs of `NA` of length 1 with 1
# leave leading and trailing NA (exclude first and last group)
d2[ , value := replace(value, is.na(value) & n == 1 &
                         g != min(g) & g != max(g), 1),
    by = .(variable)][ 
      , `:=`(g = NULL, n = NULL)] # clean-up
d2
#     variable value
#  1:       x1    NA
#  2:       x1     1
#  3:       x1     1
#  4:       x1     1
#  5:       x1     1
#  6:       x1    NA
#  7:       x2     1
#  8:       x2     1
#  9:       x2     1
# 10:       x2    NA
# 11:       x2    NA
# 12:       x2     1

【讨论】:

    【解决方案2】:

    这是基本 R 中的一种方法。基本思想是首先将 NA 替换为 0(这样rle 的输出会提供更多信息),然后调整此输出并重建它,以便 isolated 0 已被 1 取代。最后,rle() 的结果如你所愿:

    > x <- c(NA, NA, 1, NA, NA, 1, NA, 1, 1, 1, NA, NA, NA)
    > x[is.na(x)] <- 0
    > temp.data = rle(x)
    > temp.data$values[temp.data$values == 0 & temp.data$lengths == 1] <- 1
    > y <- inverse.rle(temp.data)
    > rle(y)
    Run Length Encoding
      lengths: int [1:5] 2 1 2 5 3
      values : num [1:5] 0 1 0 1 0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-03
      • 2021-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-22
      相关资源
      最近更新 更多