我正试图了解我的面板数据集中的缺失类型。我认为可能有三种情况:
我不是在寻找直接改变它们或填充它们的函数。相反,我想在得知问题之后决定如何处理它们。
如何摆脱领先的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中解决它们
对于领导NA,我仍然可以完成它,但感觉超级笨拙:
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]
我想类似的事情可以用max和最后一个NA的线索来完成,但是我无法理解差距,这对我来说是最重要的。我在网上找到的解决方案通常直接填写,删除或转移这些NA,我只是想看看。
所需的输出将是:
领导NAs:
Data[1:5]
间隙:
Data[60:65]
NA的结尾:
Data[145:150]
但是我想通过检查三种类型NA的位置来获取这些,因为我的实际数据集很大,需要手动检查。
编辑:我应该在我的真实数据集中添加它,我不知道每个人何时开始报告数据。所以:
Data[is.na(Petal.Length), time, by= Species]
不会帮助我。
答案 0 :(得分:1)
好像你可以在这里定义function
作为帮助:
my.fun <- function(spe){
k1 <- intersect(which(dat$Species == spe), which(is.na(dat$Petal.Length)))
k2 <- intersect(which(dat$Species == spe), which(!is.na(dat$Petal.Length)))
mintime <- min(dat$time[k2])
mintime.na <- min(dat$time[k1])
c <- (length(k1) > 0) && (mintime.na <= mintime)
if(c){
x <- cbind(dat[k1,], mintime)
return(x)
}
}
species.list <- as.character(unique(Data$Species))
sapply(species.list, my.fun)
# returns
$setosa
Species Petal.Length time mintime
1: setosa NA 1951 1956
2: setosa NA 1952 1956
3: setosa NA 1953 1956
4: setosa NA 1954 1956
5: setosa NA 1955 1956
$versicolor
NULL
$virginica
NULL
虽然Petal.Length
&#34;中存在所有差距,但我对你的意思仍然不清楚。
答案 1 :(得分:1)
一种方式:
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向量。然后,它会为某些特定的运行分配特殊代码,以后可以用于过滤。