user7868794
user7868794

Reputation:

Value replacement of dataframe - R

I have two dataframes.

One:

>df1            a     b     c     d 
     W_1       NA    NA    NA    NA  
     W_2        2     2     2     4   
     W_3        4     2     2     4  
     W_4       NA    NA    NA    NA  

Second:

>df2        a     b        c       d 
    W_1   TRUE   FALSE   FALSE   FALSE  
    W_2   FALSE  TRUE    FALSE   TRUE   
    W_3   TRUE   FALSE   FALSE   TRUE  
    W_4   FALSE  TRUE    FALSE   TRUE  

I want to replace places in first dataframe with NA, where in second dataframe value is FALSE.

The output should be:

           a     b     c     d 
W_1       NA    NA    NA    NA  
W_2       NA     2    NA     4   
W_3        4    NA    NA     4  
W_4       NA    NA    NA    NA 

This is my code:

for (i in nrow(df2)) {
  for (j in 1:ncol(df2)) {
     a = df2[i,j]
    if (a == FALSE) {
       df1[i,j] = NA
    }
  }
}

While I don't get any errors returned, the code doesn't work either. The first dataframe remains unchanged. Any suggestions what may be wrong?

Thanks for help.

Upvotes: 0

Views: 70

Answers (2)

akrun
akrun

Reputation: 886938

We can do this with the efficient set from data.table

library(data.table)
setDT(df1)
for(j in seq_along(df1)){
 set(df1, i = which(!df2[[j]]), j=j, value = NA)
 }

df1
#    a  b  c  d
#1: NA NA NA NA
#2: NA  2 NA  4
#3:  4 NA NA  4
#4: NA NA NA NA

As @Frank mentioned in the comments, it will also work without converting to data.table

for(j in seq_along(df1)){
    set(df1, i = which(!df2[[j]]), j=j, value = NA)
  }
df1
#     a  b  c  d
#W_1 NA NA NA NA
#W_2 NA  2 NA  4
#W_3  4 NA NA  4
#W_4 NA NA NA NA

Upvotes: 1

Cath
Cath

Reputation: 24074

If the rows/cols of df2 matches exactly the ones of df1, you can just use the logical values in df2 to replace what you want in df1:

df1[!df2] <- NA

@Frank 's way works likewise:

is.na(df1) <- !df2

Example:

df1 <- data.frame(matrix(1:16, ncol=4))
set.seed(123)
df2 <- data.frame(matrix(sample(c(TRUE, FALSE), 16, replace=TRUE), ncol=4))
df1[!df2] <- NA # or is.na(df1) <- !df2
df1
#  X1 X2 X3 X4
#1  1 NA NA NA
#2 NA  6 10 NA
#3  3 NA NA 15
#4 NA NA 12 NA

Upvotes: 5

Related Questions