简体   繁体   中英

Replacing 0 in particular order using nested if and for loop in r

i'm trying to solve the following by using for and nested if in r: my data for price available is: 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)

the problem: to replace 0 before the 1st occurrence of price with value of the 1st occurrence, then replace 0 after 1st occurrence with the value of 1st occurrence until 2nd occurrence of price and so on. The 0 after last occurrence of price should be replaced with the value of last occurrence.

I have used the following code:

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
}

I get the following result after this:

[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

which is exactly what i want. The problem is i get error by using the above code:

Error in if (m > priceposition2[i] && m < priceposition2[i + 1]) { : 
 missing value where TRUE/FALSE needed

Is there something that i'm doing wrong? Also is there an alternative using apply family for the above problem?

You could use na.locf from package zoo to do this. Basically, you first want to replace all zeros with NA. Then use na.locf forwards with na.rm = FALSE to keep leading NAs. And then use na.locf backwards with fromLast=TRUE to change the leading NAs to the first value.

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]

You can use findInterval across the indices of the entire vector, using the locations of the above-zero values as the interval boundaries. Then you use those interval numbers to swap in the correct above-zero values (with the first one used for two intervals).

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]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM