我正在尝试了解我的面板数据集中的缺失类型。我觉得可以分为三种情况:
- 领先的 NA;在某个人的数据开始之前
- 差距;因此在数据重新启动后的几个时间段内丢失数据
- NA 在末尾strong>;如果一个人提前停止,数据的
我不是在寻找直接更改或填充它们的函数。相反,我想在了解问题后决定如何处理它们。
如何去掉前导 NA(但不是如何查看你有多少)已解决 here .解决所有 NA 的问题很简单:
library(data.table)
Data <- as.data.table(iris)[,.(Species,Petal.Length)]
Data[, time := rep(1951:2000,3)]
Data[c(1:5,60:65,145:150), Petal.Length := NA]
# in Petal lenth setosa has lead NA's, versicolor a gap, virginica NA's at the end
Data[is.na(Petal.Length)] # this is a mix of all three types of NA's
但我想区分这三种情况。理想情况下,我想直接在 data.table 中将它们作为
- “给我一个数据表,其中包含在 Petal.Length 中具有前导 NA 的所有观察结果”
- “给我一个数据表,其中包含 Petal.Length 中存在间隙的观察值”
- “给我一个数据表,其中包含每个人在过去一段时间内的 NA 观察结果”
对于 NA 主管,我仍然可以完成它,但感觉 super 笨拙:
Data[!is.na(Petal.Length), firstobs := ifelse(min(time) == time, 1, 0), by = Species]
Data[, mintime := max(firstobs * time, na.rm = T), by = Species]
Data[time < mintime]
我想对于最后一个 NA 的 max 和 leads 也可以做类似的事情,但我无法理解差距,这些对我来说是最重要的。我在网上找到的解决方案一般都是直接填、删、移这些NA的,我就看看。
期望的输出是:
领先的 NA:
Data[1:5]
差距:
Data[60:65]
NA 在末尾:
Data[145:150]
但我想通过检查三种类型的 NA 的位置来获取这些信息,因为我的实际数据集太大而无法手动检查。
编辑:我应该在我的真实数据集中添加,我不知道每个人何时开始报告数据。所以:
Data[is.na(Petal.Length), time, by= Species]
不会帮助我。
最佳答案
一种方式:
Data[, g := {
r = rleid(vna <- is.na(Petal.Length))
if (first(vna)) r = replace(r, r == 1L, 0L)
if ( last(vna)) r = replace(r, r == last(r), 9999L)
replace(r, !vna, NA_integer_)
}, by=Species]
确认它与 OP 预期的行相匹配...
> # leading
> Data[g == 0L, which = TRUE]
[1] 1 2 3 4 5
> # trailing
> Data[g == 9999L, which = TRUE]
[1] 145 146 147 148 149 150
> # gaps
> Data[!.(c(0L, 9999L, NA_integer_)), on="g", which = TRUE]
[1] 60 61 62 63 64 65
要仅获取子集,请在不使用 which = TRUE
参数的情况下使用这些命令。
除了识别三个类别中每一个类别中的行之外,这种方法还通过不同的 g
值识别间隙(如果有多个)。
工作原理
您可以插入一些 print
和 cat
指令来跟踪每个对象在循环期间的样子:
csprintf <- function(s, ...) cat(sprintf(s, ...))
Data[, g := {
csprintf("Group: %s = %s %s\n", toString(names(.BY)), toString(.BY), strrep("*", 60))
r = rleid(vna <- is.na(Petal.Length))
csprintf("NA positions and initial grouping vector:\n")
print(data.table(Petal.Length, r, vna))
if (first(vna)) r = replace(r, r == 1L, 0L)
csprintf("NA positions and grouping vector after tagging leading NAs:\n")
print(data.table(Petal.Length, r, vna))
if ( last(vna)) r = replace(r, r == last(r), 9999L)
csprintf("NA positions and grouping vector after tagging trailing NAs:\n")
print(data.table(Petal.Length, r, vna))
r = replace(r, !vna, NA_integer_)
csprintf("NA positions and grouping vector after tagging non-NAs:\n")
print(data.table(Petal.Length, r, vna))
cat(strrep("\n", 2))
r
}, by=Species]
差不多,它创建了指示 NA 位置的 vna 向量和在 vna 中运行的 r 向量。然后它将特殊代码分配给某些特定的运行,这些代码稍后可用于过滤。
关于r - 如何按类别在 data.table 列中查找(而不是替换)前导 NA、间隙和最终 NA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49426398/