1

I've been trying to figure that out for a whole day now, but my understanding of loops is just not the best. I basically have 3 data frames. They contain several columns. I want to check each data frame at a time. If one value in a column is -9999 (NA), I want to replace it with a value from the other data frames (if the same value from the 2nd data frame is -9999 too, it should take the value from the 3rd one).

I figured it out with if else. I just can't get it into a for loop. So I have to type each column by hand, which takes a lot of time, since I have many columns with weird names. So here's my example, in simple form. Maybe some can help me. Thanks a lot, Susi

par1 <- c(1,2,3,4)
par2 <- c(1,2,3,0)
par3 <- c(1,0,3,8)
par4 <- c(1,0,3,9)

r <- data.frame(par1, par2, par3, par4)
d <- data.frame(par1, par2, par3, par4)
b <- data.frame(par1, par2, par3, par4)

r$par1[4] <- -9999

gap_filling <- function(x,y,z){
  ifelse (x == -9999, 
          ifelse(y==-9999, z, y),
          x)
} ## this is the function I wrote to shorten it a little bit

r$par1 <- gap_filling(r$par1, d$par1, b$par1)
r$par2 <- gap_filling(r$par2, d$par2, b$par2)
r$par3 <- gap_filling(r$par3, d$par3, b$par3)
r$par4 <-gap_filling(r$par4, d$par4, b$par4)

### this is just the replacing for the first data frame. I need to do the same with the other two too

2 Answers 2

1

(edited version, thanks to Jake Burkead's comment)

What you really want is the power of logical indexing.

For example:

r[r==-9999] <- d[r==-9999]
r[r==-9999] <- b[r==-9999]
# # Alternate writing, if you have 'NA' instead of -9999
# # r[is.na(r)] <- matrix.d[is.na(r)]
# # r[is.na(r)] <- matrix.b[is.na(r)]
Sign up to request clarification or add additional context in comments.

4 Comments

You can do this data.frames as well
Something like ifelse(r == -9999, ifelse(b == -9999, d, as.matrix(b)), as.matrix(r)) could, also, be helpful.
Hey, thanks for your answers, the problem is, that my data frames don't have the same lengths. Also I would like to replace only some columns in the data frames, not the whole data.frame. So your answer gives me an error message, unfortunately.I know I can subset the data.frame. I was just looking for a shorter answer.
@user3330494: then you need to clarify your question a lot... because my understanding of it changed completely with your comment. It could be even better if you ask a new question :)
0

You could organize r, b, d in a named list and proceed as @Jealie and @JakeBurkhead suggested:

l <- list(r=r, d=d, b=b) 
invisible(lapply(1:length(l), function(i) { 
  for (x in setdiff(1:length(l), i))      
       l[[i]] [ l[[i]] == -9999] <<- l[[x]] [ l[[i]] == -9999]
}))
invisible(list2env(l, envir=.GlobalEnv)) # overwrite existing r, d, b  

1 Comment

Hey, thank you. I tried that with my data.frames, but I get this error message: Error during wrapup: cannot coerce type 'promise' to vector of type 'character' Error during wrapup: target context is not on the stack Error during wrapup: cannot coerce type 'promise' to vector of type 'character' Error during wrapup: target context is not on the stack I guess the problem here is also, that my data frames don't have the same lengths?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.