【发布时间】:2018-02-23 16:47:11
【问题描述】:
我有一个包含 2718 个观察值的数据框,其中一列是感兴趣的。这是使用diff() 创建的第一个差异系列。为方便起见,让我们创建一个类似于数据的假向量,并假装v 是第一个差分序列。引入NAs 使其与原始数据相似。
# Create fake first difference series vector v
v <- runif(2718, -0.05, 0.05)
v <- append(NA, diff(v))
# Insert NAs at the beginning and end
v[c(1:8, 2712:2718)] <- NA
# Insert some NAs at random places in v
ind <- which(v %in% sample(v, 7))
v[ind] <- NA
我对 v 的序列感兴趣,这些序列显示了递增和递减的行为。具体来说,我想分别提取连续增加和减少的v 的序列。在递增序列中,v 的每个元素不能小于其前一个元素,而在递减序列中,v 的每个元素不能大于其前一个元素。在绘制v 时尝试想象这一点:只要曲线不减小(即上升或保持水平),它就是一个递增序列,只要曲线不增加(即下降或保持水平),它就是一个下降序列顺序。
为了澄清,这个过程可以这样解释:
- 从头开始,查看
v中的给定值i,并将其与前一个i-1进行比较 - 如果
i大于或等于i-1,则序列符合递增条件;如果i小于或等于i-1,则序列符合递减条件。 - 通过提取
ith 元素存储此类部分的增加/减少 - 一旦下一个值大于(对于递减序列)或小于(对于递增序列)前一个值,每个序列就会终止
- 如果从到
i-1到i没有变化(即i-1和i相等),则序列继续,就像NA发生时一样
由于v 是第一个差分系列,提取的元素i(第三个要点)已经代表了增加/减少。目前,我不想限制序列的长度,因此一个序列可能已经由两个元素给出。
我想将v 的ith 元素存储在一个新向量中(例如inc.v 和dec.v),然后找到序列的最大和平均增加/减少,以及最大和平均长度这些序列。元素应该存储在inc.v 或dec.v 相对于它们在v 中的原始位置,所以我可以追踪它们。 inc.v 和dec.v 中的每一个序列用NA 元素分隔时应该很容易区分。
我尝试使用 for 循环和条件语句编写此代码,但没有成功:
inc.v <- NULL
dec.v <- NULL
for (i in 2:length(v)) {
if(!v[i] < v[i-1] | is.na(v[i])) {
inc.v[i] <- v[i]
} else if (!v[i] > v[i-1] | is.na(v[i])) {
dec.v[i] <- v[i]
} else {
next
}
}
if 和 else if 语句代表第五个要点。我知道当i 等于i-1 时,它既可以作为递增序列也可以作为递减序列,并且应该将其添加到之前存储的任何序列中。我只是不知道如何实现它。我认为序列会很短,因为数据很嘈杂,而且不减少/不增加的时期不会持续很长时间。因此,最好也尝试此操作,例如50/100 点移动平均值:
# A symmetric 50 points moving average for v
f50 <- rep(1/51,51)
v_smooth <- filter(v, f50, sides = 2)
到目前为止,当运行循环时,对第一个条件的评估会导致 NA,给我错误:
Error in if (!v[i] < v[i - 1] | is.na(v[i])) { :
missing value where TRUE/FALSE needed
我不太明白这里发生了什么,因为 is.na() 语句应该确保 TRUE 或 FALSE 参数?!
很高兴听到你的想法!
【问题讨论】:
-
我真的不知道我是否理解这个问题。
dec.v <- v[which(diff(v) < 0)]有什么问题?diff(v) > 0也一样?请注意,由于您有NA值,因此您将需要which。
标签: r sequence na difference