Estoy tratando de resolver lo siguiente usando for y anidado si en r: mis datos para el precio disponible son: 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)

El problema: reemplazar 0 antes de la primera aparición del precio con el valor de la primera aparición, luego reemplazar 0 después de la primera aparición con el valor de la primera aparición hasta la segunda aparición del precio y así sucesivamente. El 0 después de la última aparición del precio debe reemplazarse con el valor de la última aparición.

He usado el siguiente código:

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
}

Obtengo el siguiente resultado después de esto:

[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

Que es exactamente lo que quiero El problema es que obtengo un error al usar el código anterior:

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

¿Hay algo que estoy haciendo mal? ¿También hay una alternativa usando el uso de la familia para el problema anterior?

1
Jayesh Jinde 26 jun. 2017 a las 18:35

3 respuestas

La mejor respuesta

Puede usar na.locf del paquete zoo para hacer esto. Básicamente, primero desea reemplazar todos los ceros con NA. Luego use na.locf hacia adelante con na.rm = FALSE para seguir liderando NA. Y luego use na.locf hacia atrás con fromLast=TRUE para cambiar las NA principales al primer valor.

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
3
Pierre Lapointe 26 jun. 2017 a las 15:49

Puede utilizar findInterval en los índices de todo el vector, utilizando las ubicaciones de los valores superiores a cero como límites de intervalo. Luego, usa esos números de intervalo para intercambiar los valores correctos por encima de cero (con el primero usado para dos intervalos).

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]
1
Nathan Werth 26 jun. 2017 a las 15:50

Reduce en la base R se adapta bien a lo que buscas (v es tu vector):

Reduce(function(x,y) ifelse(y==0, x, y), v, accumulate=TRUE, init = v[v>0][1])[-1]
3
989 26 jun. 2017 a las 16:26