It's usually easier to manually introduce
NAs. You don't need
if if there's no code to be evaluated if it's true; inequalities already evaluate to a Boolean. Really, all you need is
df1[((df2 < 0.9) & (df2 > 0.6)) | ((df2 < 0.4) & (df2 > 0.1))] <- NA
df1 so it looks like
> df1 name sam1 sam2 sam3 1 AZ1 2.65 2.56 2.65 2 AX1 NA 2.41 2.85 3 AX2 2.45 2.45 NA
With long Boolean tests like this, watch your parentheses, especially if you've got multiple ranges.
If called on the
df2 exactly as above, this code will raise warnings
Warning messages: 1: In Ops.factor(left, right) : ‘<’ not meaningful for factors 2: In Ops.factor(left, right) : ‘>’ not meaningful for factors 3: In Ops.factor(left, right) : ‘<’ not meaningful for factors 4: In Ops.factor(left, right) : ‘>’ not meaningful for factors
df2$name is a factor. Since factors store their values as numbers (mapped to levels), R is warning that it's not performing the inequality operations on those values, which we don't want it to do, anyway. Since it does nothing to the
name column, the result it what we want regardless of the warnings.
The warnings can be avoided wholly by changing
name to character, or not turning it into a factor in the first place. Either specify the option
stringsAsFactors = FALSE in
read.table when you read in the data, or prepend the above line with
df2$name <- as.character(df2$name)
Since it's obvious that R won't compare a string and a number with an inequality, it will no longer raise warnings.