user3330494
user3330494

Reputation: 11

R replacing values from multiple columns of multiple data frames

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

Upvotes: 1

Views: 1091

Answers (2)

lukeA
lukeA

Reputation: 54237

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  

Upvotes: 0

Jealie
Jealie

Reputation: 6267

(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)]

Upvotes: 1

Related Questions