Reputation:
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
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
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