r - 如何按类别在 data.table 列中查找(而不是替换)前导 NA、间隙和最终 NA

标签 r data.table

我正在尝试了解我的面板数据集中的缺失类型。我觉得可以分为三种情况:

  1. 领先的 NA;在某个人的数据开始之前
  2. 差距;因此在数据重新启动后的几个时间段内丢失数据
  3. NA 在末尾;如果一个人提前停止,数据的

我不是在寻找直接更改或填充它们的函数。相反,我想在了解问题后决定如何处理它们。

如何去掉前导 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 中将它们作为

  1. “给我一个数据表,其中包含在 Petal.Length 中具有前导 NA 的所有观察结果”
  2. “给我一个数据表,其中包含 Petal.Length 中存在间隙的观察值”
  3. “给我一个数据表,其中包含每个人在过去一段时间内的 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 值识别间隙(如果有多个)。


工作原理

您可以插入一些 printcat 指令来跟踪每个对象在循环期间的样子:

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/

相关文章:

r - dplyr - 重命名由 readr 创建的列 [EMPTY]

r - data.table:每组过去 24 小时内的观察子集

r - 为每个用户创建具有多个条件的累积计数器变量

r - 更改vistime中的字体

r - 具有位置向量的向量子集列表

sql-server - R 的存储过程参数

r - 使用 data.table 函数 foverlaps 查找两个表中重叠范围的交集

r - 如何将数据表rolling join条件从弱不等式改为严格不等式?

r - 使用 data.table 和plotly 堆积条形图

java - 如何将类的Java对象返回到R中(使用rjava包)