对于向量,确定所有值都为 NA(或某个值)的索引

For a vector, determine the index past which all values are NA (or some value)

所以,我有调查数据,我想解决多次管理调查的问题(计算机出现故障、浏览器关闭、人们重新启动)。假设我有案例 x1 和 x2,由同一个人按顺序完成(这里,已经作为向量提取)

x1 <- c(1:35, rep(NA, 65))
x2 <- c(-1:-95, rep(NA, 5))

鉴于我可以知道 x1 先发生,我想确定 x1 中的第一个 NA,所有后续条目都是 NA(位置 36),因此我可以结合这些案例生成仅代表第一印象的数据。

我想找到一个可以让我做到这一点的函数:

n <- {function that computes this value}
x <- c(x1[1:(n-1)], x2[n:length(x2)])

导致这里的输出相当于:

c(1:35, -36:-95, rep(NA, 5))

length(na.omit(x1)) + 1这样的方法是行不通的,因为在结束点之前可能有NA,扰乱了索引。例如,如果

,它仍然需要找到索引 36
 x1 <- c(1:12, NA, 13:35, rep(NA, 65))

97% 的人需要它只适用于 NA,但通用解决方案也很好(即,如果需要,也可以匹配 "" 或类似的东西。)

你几乎自己解决了这个问题。请试试这个

x3 <- c(x1[1:(head(which(is.na(x1)),1) - 1)], x2[head(which(is.na(x1)),1):length(x2)])

希望你能转成函数

您问题的数据

x1 <- c(1:35, rep(NA, 65))
x2 <- c(-1:-95, rep(NA, 5))
n <- max( which(diff(is.na(x1)) == 1)) 
c(x1[1:n-1], x2[n:length(x2)])

# [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23
# [24]  24  25  26  27  28  29  30  31  32  33  34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46
# [47] -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69
# [70] -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92
# [93] -93 -94 -95  NA  NA  NA  NA  NA

另一个例子:

x1 <- c(1:35, rep(NA, 35), 1:20, rep(NA, 10))
x2 <- c(-1:-95, rep(NA, 5))
n <- max( which(diff(is.na(x1)) == 1)) 
c(x1[1:n-1], x2[n:length(x2)])
# [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23
# [24]  24  25  26  27  28  29  30  31  32  33  34  35  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
# [47]  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
# [70]  NA   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19 -90 -91 -92
# [93] -93 -94 -95  NA  NA  NA  NA  NA

使用运行-长度编码

n <- with(rle(is.na(x1)), lengths[length(lengths) -1 ] + 1 )

x <- c(x1[1:(n-1)], x2[n:length(x2)])

# [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29
# [30]  30  31  32  33  34  35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58
# [59] -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87
# [88] -88 -89 -90 -91 -92 -93 -94 -95  NA  NA  NA  NA  NA

as rle 给出 NA 的 运行 的长度(或您指定的任何内容)。并且,您想使用这些 运行 中的最后一个,因此我们可以选择最后一个 运行

的起点
> rle(is.na(x1))
Run Length Encoding
  lengths: int [1:2] 35 65
  values : logi [1:2] FALSE TRUE

这可以用一个非常简单的方法解决 ifelse:

x3 = ifelse(is.na(x1),x2,x1)

结果:

> x3
  [1]   1   2   3   4   5   6   7   8   9  10  11  12  13
 [14]  14  15  16  17  18  19  20  21  22  23  24  25  26
 [27]  27  28  29  30  31  32  33  34  35 -36 -37 -38 -39
 [40] -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52
 [53] -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65
 [66] -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78
 [79] -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91
 [92] -92 -93 -94 -95  NA  NA  NA  NA  NA

如果您在 x1 中的最后一个有效条目之前没有 NA,则此方法有效。如果是这种情况,以前的 NA 可能意味着用户跳过了这个问题。如果你想在 x1 中保留以前的 NA,请执行:

lastValidX1 =  max(which(!is.na(x1)))
x3 = c( x1[1:lastValidX1] , x2[(lastValidX1+1):length(x2)] )

示例:

x1 <- c(1:19,NA,21:35, rep(NA, 65))
x2 <- c(-1:-95, rep(NA, 5))

lastValidX1 =  max(which(!is.na(x1)))
x3 = c( x1[1:lastValidX1] , x2[(lastValidX1+1):length(x2)] )

> x3
  [1]   1   2   3   4   5   6   7   8   9  10  11  12  13
 [14]  14  15  16  17  18  19  NA  21  22  23  24  25  26
 [27]  27  28  29  30  31  32  33  34  35 -36 -37 -38 -39
 [40] -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52
 [53] -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65
 [66] -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78
 [79] -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91
 [92] -92 -93 -94 -95  NA  NA  NA  NA  NA

> lastValidX1
[1] 35