0

I am getting a warning: "the condition has length > 1 and only the first element will be used", when I try to use the following function fixED:

> fixED
function(x) {
    if(nchar(x) == 5) {
        return(x)
    }
    else if(nchar(x) == 3) {
        return(gsub('^(.{2})(.*)$', '\\100\\2', x))
    } 
    else if(nchar(x) == 4) {
        return(gsub('^(.{2})(.*)$', '\\10\\2', x))
    }
}

Here is the full set of warnings:

Warning messages:
1: In if (nchar(x) == 5) { :
  the condition has length > 1 and only the first element will be used
2: In if (nchar(x) == 4) { :
  the condition has length > 1 and only the first element will be used
3: In if (nchar(x) == 3) { :
  the condition has length > 1 and only the first element will be used

I know that there are a few other questions on here that are similar to this but none of them has clarified for me what the problem may be. It sounds to me as though R things that the logical expressions inside the if statements are returning a vector of >1.

However, I don't understand how that could be the case since I'm fairly certain that they are a logical vector of 1. Indeed, the following seems to demonstrate that:

> length((nchar("43") ==2))
[1] 1

Can anyone see what the problem is here? I'm stumped at the moment. The data to which I'd like to apply this function looks like this:

> df.short
     AD ED
9918 57 84
9919 57 84
9920 57 84
9921 57 84
9922 57 84
9923 57 84
9924 57 84
9925 57 85
9926 57 85
9927 57 85
9928 57 85

I apply it like so:

df.short$test <- fixED(paste(df.short$AD, df.short$ED, sep=""))
fraxture
  • 5,113
  • 4
  • 43
  • 83
  • 1
    Possible duplicate of [IF returns "the condition has length > 1 and only the first element will be used"](https://stackoverflow.com/questions/22150423/if-returns-the-condition-has-length-1-and-only-the-first-element-will-be-used) – G5W Oct 06 '17 at 16:34
  • Probably a duplicate...but to help out, your issue is that you are indeed passing a vector longer than 1. To convince yourself, do this `length(paste(df.short$AD, df.short$ED, sep=""))`. So the quick solution without changing your function is to put it in an *apply: `sapply(paste(df.short$AD, df.short$ED, sep=""), fixED)`. A completely re-worked fix would be to use the vector output of `nchar` to replace the elements of `x` that meet your conditions: e.g., `x[nchar(x) == 3] <- gsub('^(.{2})(.*)$', '\\100\\2', x[nchar(x) == 3])`; finally return `x` at the end of your new function – Andy Rominger Oct 06 '17 at 17:05

1 Answers1

1

This,

paste(df.short$AD, df.short$ED, sep="")

is a vector, not of length 1, so when you pass that to your function, you are testing a vector against a scalar:

nchar(x) == 5

I suggest looping over your function using an apply function, something like

mapply(fixED, x = paste(df.short$AD, df.short$ED, sep=""))
ssp3nc3r
  • 3,662
  • 2
  • 13
  • 23