我有一个由观察和模型预测数据组成的data.frame。最小的示例数据集可能如下所示:
myData <- data.frame(tree=c(rep("A", 20)), doy=c(seq(75, 94)), count=c(NA,NA,NA,NA,0,NA,NA,NA,NA,1,NA,NA,NA,NA,2,NA,NA,NA,NA,NA), pred=c(0,0,0,0,1,1,1,2,2,2,2,3,3,3,3,6,9,12,20,44))
计数列表示何时进行观察并在一整天内对预测进行建模,实际上将数据内插到日期级别(每5天)。
我想有条件地过滤此数据集,以便最终将预测截断到与观察值相同的范围,实际上保持计数开始和结束之间的所有预测(即删除前导和尾随行/值的时间)它们对应于计数列中的NA)。对于这个例子,理想的结果是:
tree doy count pred
5 A 79 0 1
6 A 80 NA 1
7 A 81 NA 1
8 A 82 NA 2
9 A 83 NA 2
10 A 84 1 2
11 A 85 NA 2
12 A 86 NA 3
13 A 87 NA 3
14 A 88 NA 3
15 A 89 2 3
我尝试通过将filter
与first
和last
相结合来解决此问题,考虑使用条件mutate
来创建确定是否存在的列在之前的doy中观察(可能使用lag
)并用1或0填充并使用该输出进行过滤,甚至创建第二个data.frame,其中包含可以连接到此数据的正确doy范围
在我对StackOverflow的搜索中,我遇到了以下似乎很接近但仍然不是我需要的问题:
Select first observed data and utilize mutate
Conditional filtering based on the level of a factor R
我的实际数据集在多年中有多棵树(每棵树/年具有不同的观察时段,具体取决于站点的高度等)。我目前正在我的代码中实现dplyr
包,因此在该框架内的答案会很棒但是对任何解决方案都很满意。
答案 0 :(得分:1)
尝试
indx <- which(!is.na(myData$count))
myData[seq(indx[1], indx[length(indx)]),]
# tree doy count pred
#5 A 79 0 1
#6 A 80 NA 1
#7 A 81 NA 1
#8 A 82 NA 2
#9 A 83 NA 2
#10 A 84 1 2
#11 A 85 NA 2
#12 A 86 NA 3
#13 A 87 NA 3
#14 A 88 NA 3
#15 A 89 2 3
如果这是基于群组
ind <- with(myData, ave(!is.na(count), tree,
FUN=function(x) cumsum(x)>0 & rev(cumsum(rev(x))>0)))
myData[ind,]
# tree doy count pred
#5 A 79 0 1
#6 A 80 NA 1
#7 A 81 NA 1
#8 A 82 NA 2
#9 A 83 NA 2
#10 A 84 1 2
#11 A 85 NA 2
#12 A 86 NA 3
#13 A 87 NA 3
#14 A 88 NA 3
#15 A 89 2 3
或使用na.trim
zoo
library(zoo)
do.call(rbind,by(myData, myData$tree, FUN=na.trim))
或使用data.table
library(data.table)
setDT(myData)[,.SD[do.call(`:`,as.list(range(.I[!is.na(count)])))] , tree]
# tree doy count pred
#1: A 79 0 1
#2: A 80 NA 1
#3: A 81 NA 1
#4: A 82 NA 2
#5: A 83 NA 2
#6: A 84 1 2
#7: A 85 NA 2
#8: A 86 NA 3
#9: A 87 NA 3
#10: A 88 NA 3
#11: A 89 2 3
答案 1 :(得分:1)
我认为您只是希望将行限制在第一个和最后一个非NA计数值之间:
myData[seq(min(which(!is.na(myData$count))), max(which(!is.na(myData$count)))),]
# tree doy count pred
# 5 A 79 0 1
# 6 A 80 NA 1
# 7 A 81 NA 1
# 8 A 82 NA 2
# 9 A 83 NA 2
# 10 A 84 1 2
# 11 A 85 NA 2
# 12 A 86 NA 3
# 13 A 87 NA 3
# 14 A 88 NA 3
# 15 A 89 2 3
在dplyr
语法中,按tree
变量进行分组:
library(dplyr)
myData %>%
group_by(tree) %>%
filter(seq_along(count) >= min(which(!is.na(count))) &
seq_along(count) <= max(which(!is.na(count))))
# Source: local data frame [11 x 4]
# Groups: tree
#
# tree doy count pred
# 1 A 79 0 1
# 2 A 80 NA 1
# 3 A 81 NA 1
# 4 A 82 NA 2
# 5 A 83 NA 2
# 6 A 84 1 2
# 7 A 85 NA 2
# 8 A 86 NA 3
# 9 A 87 NA 3
# 10 A 88 NA 3
# 11 A 89 2 3