sedeh
sedeh

Reputation: 7313

Using colon to specify a sequence in function

I just started r about a week ago. In my directory, I have csv files named 001, 002,...010,...331. In my partial function below, the user is requested to enter id (e.g. 1:9). The id is then converted into 001, 002, 003,...009. However, if the user enters say 1:10 for the id, the function will output id [10] as "0010" instead of as "010". This causes the rest of my function to fail. Any suggestions on what might be going on? If I enter 1:10, I want to get 001, 002, 003, 004, 005, 006, 007, 008, 009 and 010.

pollutantmean <- function(directory, pollutant, id) {

    if((id>=1) && (id<10)) {
            fn <- paste("00",id,sep="")
            print(fn)
    } else if((id>=10) && (id<=99)) {
            fn <- paste("0",id,sep="")
            print(fn)
    } else {
            fn <- id
            print(fn)
    }

Please I don't want to use R apply function for this. I have not gotten that far.

Upvotes: 0

Views: 832

Answers (3)

IRTFM
IRTFM

Reputation: 263451

This puts leading "0"'s to a width of 3 characters with the numeric values being taken as stings.

sprintf("%03s", 1:10)
 [1] "001" "002" "003" "004" "005" "006" "007" "008" "009" "010"

Upvotes: 3

Stedy
Stedy

Reputation: 7469

Your function is close but its only evaluating a single number id. I added a for loop to handle a range of numbers:

pollutantmean <- function(idrange) {
  for(id in idrange){
  if((id>=1) && (id<10)) {
    fn <- paste("00",id,sep="")
    print(fn)
  } else if((id>=10) && (id<=99)) {
    fn <- paste("0",id,sep="")
    print(fn)
  } else {
    fn <- id
    print(fn)
  }}
}

I removed the directory and pollutant arguments but they can easily be added back in. This function will evaluate all the numbers in the range of interest and print them out:

R> pollutantmean(1:10)
[1] "001"
[1] "002"
[1] "003"
[1] "004"
[1] "005"
[1] "006"
[1] "007"
[1] "008"
[1] "009"
[1] "010"
R> 

Upvotes: 2

MrFlick
MrFlick

Reputation: 206486

The problems is that you are using an if statement and the short circuiting && operator. In this case && will only look at the first element of the vector id and make a decision there. In this case (1>=1) && (1<10) so it executes that first block. Then you call fn <- paste("00",id,sep="") which is vectorized so it operates on the entire id vector so it adds '00' to every element. You seem to be treating the function like there is some implicit loop but there is not.

Of course @thelastemail's suggestion of fn <- sprintf("%03d",id) is the right one in this case, but just for the sake of discussion, your code could be re-written as

fn <- paste(ifelse(id<10, "00", ifelse(id<100, "0", "")),id,sep="")

because ifelse does have a kind of implied loop in that it can make different decisions for every element in the vector.

Upvotes: 2

Related Questions