costebk08
costebk08

Reputation: 1359

Converting particular values to NA in a dataframe in R

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

Answers (2)

Curtis H.
Curtis H.

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

David Arenburg
David Arenburg

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

Related Questions