[英]Replacing 0 in particular order using nested if and for loop in r
我正在尝试通过使用for和嵌套在r中来解决以下问题:我的可用价格数据是:test2
test2 <- c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 399, 0, 0, 399, 0, 0, 0, 0, 399, 0, 0, 0, 0, 429, 0, 429,
0, 0, 0, 499, 0, 429, 0, 0, 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0)
问题:将第一次出现价格之前的0替换为第一次出现的值,然后将第一次出现之后的0替换为第一次出现的值,直到第二次出现价格,依此类推。 最后一次出现的价格后的0应该替换为最后一次出现的值。
我使用了以下代码:
priceposition2 <- which(test2>0)
for(i in 1:length(priceposition2)){
for(m in 1:length(test2)){
if (m <= priceposition2[1]){
test2[m] <- test2[priceposition2[1]]
} else if (m > priceposition2[1]){
if (m> priceposition2[i] && m < priceposition2[i+1]){
test2[m] <- test2[priceposition2[i]]
}else if(m> priceposition2[length(priceposition2)]){
test2[m] <- test2[priceposition2[length(priceposition2)]]
}
}
m=m+1
}
i=i+1
}
在此之后,我得到以下结果:
[1] 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399
399 399 399 399 399
[24] 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399
399 399 399 399 399
[47] 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399
399 399 399 399 399 399
[70] 399 399 399 399 399 399 399 399 429 429 429 429 429 429 499 499 429 429
429 429 429 429 529
[93] 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529
529 529 529 529 529
[116] 529 529 529 529 529 529 529 529 529 529 529 529 529 529
这正是我想要的。 问题是我通过使用上面的代码得到错误:
Error in if (m > priceposition2[i] && m < priceposition2[i + 1]) { :
missing value where TRUE/FALSE needed
我做错了什么吗? 还有解决上述问题的替代方法吗?
您可以使用来自zoo
软件包的na.locf
来执行此操作。 基本上,您首先要用NA替换所有零。 然后使用na.locf
na.rm = FALSE
na.locf
转发来保持领先的NA。 然后使用na.locf
fromLast=TRUE
向后使用fromLast=TRUE
将前导NA更改为第一个值。
priceposition2<-c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,399,0,0,399,0,
0,0,0,399,0,0,0,0,429,0,429,0,0,0,499,0,429,0,
0,0,0,0,529,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
library(zoo)
priceposition2[priceposition2==0] <- NA
na.locf(na.locf(priceposition2,na.rm = FALSE),fromLast=TRUE)
[1] 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399
[33] 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399
[65] 399 399 399 399 399 399 399 399 399 399 399 399 399 429 429 429 429 429 429 499 499 429 429 429 429 429 429 529 529 529 529 529
[97] 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529
[129] 529
Reduce
基数R非常适合您所追求的目标( v
是您的向量):
Reduce(function(x,y) ifelse(y==0, x, y), v, accumulate=TRUE, init = v[v>0][1])[-1]
您可以使用零值以上的位置作为间隔边界,在整个矢量的索引中使用findInterval
。 然后,您可以使用这些间隔号交换正确的零以上值(第一个用于两个间隔)。
above_zero <- which(test2 > 0)
carryover_from <- findInterval(seq_along(test2), c(0, above_zero))
carryover_values <- c(test2[above_zero[1]], test2[above_zero])
test2 <- carryover_values[carryover_from]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.