Reputation: 1359
I have the following data frame:
> head(newdat2)
i42 i35 i32 i31 i30 i29 i28 i27 i26
1 5 5 5 5 5 5 5 5 5
5 3 3 2 2 4 4 4 3 2
6 5 5 5 2 5 5 5 5 5
7 5 5 5 5 5 5 5 5 5
8 4 5 4 3 5 4 4 3 4
11 3 2 2 6 2 4 2 2 2
I would like to convert any values that are not 1,2,3,4, or 5 to NAs. How could I go about doing this? I have tried the following:
newdat2[(newdat2!=1)|(newdat2!=2)|(newdat2!=3)|(newdat2!=4)|(newdat2!=5)]<-NA
But this just makes all the values NA I also also tried some combos of sapply and ifelse, but nothing is working. Any thoughts? Thank you!
Upvotes: 1
Views: 67
Reputation: 78
Your approach can be made to work, you just need to get the boolean logic right. David Arenburg's answer offers a cleaner approach anyway, but you may find it useful to understand "what went wrong" with your attempt.
Note that (x!=1)|(x!=2)
will evaluate to true for both 1 and 2 (as well as any other number): when x
is 1 the x!=2
clause is true, and when x
is 2 the x!=1
clause is true. To get all numbers that are neither 1 nor 2 you want to use the &
connective: (x!=1)&(x!=2)
. This is an application of one of two extremely useful principles known as DeMorgan's laws, which state that, for any boolean expressions P
and Q
, !(P or Q) == (!P) and (!Q)
, and !(P and Q) == (!P) or (!Q)
.
It is not too hard to show that this extends to arbitrarily many expressions, so in your case the correct code would be
newdat2[(newdat2!=1)&(newdat2!=2)&(newdat2!=3)&(newdat2!=4)&(newdat2!=5)]<-NA
Upvotes: 1
Reputation: 92300
Here's a possible implementation of the is.na<-
replacement function
df[] <- lapply(df, function(x) `is.na<-`(x, !x %in% 1:5))
# i42 i35 i32 i31 i30 i29 i28 i27 i26
# 1 5 5 5 5 5 5 5 5 5
# 5 3 3 2 2 4 4 4 3 2
# 6 5 5 5 2 5 5 5 5 5
# 7 5 5 5 5 5 5 5 5 5
# 8 4 5 4 3 5 4 4 3 4
# 11 3 2 2 NA 2 4 2 2 2
Upvotes: 4