Chuan
Chuan

Reputation: 677

write a function to read file using R

all. I find an interesting but confusion thing when I wrote codes today. I wrote a very simple function as below:

read_data <- function(x,name){
        a <- paste0(x, ".csv")
        name <- read.csv(a, header = T, sep = ",", stringsAsFactors = F)
}

(I am writing this function for a little experiment, it is stupid, I admit)

For example, I have a file named "age.csv" in the working directory. I use the above function to call:

read_data("age",age)

There is no warning or error when I run this code. I think there should be a object named age showing up in my working environment. But nothing comes up. Is that true that the read_data function creates the age object which stays in the local environment rather than in the global environment? Could anyone tell me how to fix this? Many thanks!

Upvotes: 2

Views: 1678

Answers (1)

Joris Meys
Joris Meys

Reputation: 108523

A few problems here:

  • the argument name creates an object called name in the local function environment.
  • the second line of your function overwrites that object name with the result of that call to read.csv.
  • the result of that assignment is returned invisibly but not stored. So in essence, your function creates a data frame literally called name and then gets rid of it again.

Take a look at the outcome of following code:

read_data <- function(x,name){
  cat("Name object: \n",name,"\n")
  name <- read.csv(x)
  cat("new name object: \n")
  print(name)
  cat("\n")
}

Trying it:

afile <- textConnection("A,B,C
                        1,1,1
                        1,2,3
                        3,2,1")
read_data(afile,"age")
#> Name object: 
#>  age 
#> new name object: 
#>   A B C
#> 1 1 1 1
#> 2 1 2 3
#> 3 3 2 1

I don't really understand why you do it this way, as you can just use read.csv() and store that result in an object. As said in the comments, trying to assign values outside the current environment is dangerous, and something you shouldn't do without very good reason. If you don't know when to and when not to, you don't have a very good reason and you shouldn't try to do this.

But if you must, you'll need to use the assign() function:

read_data <- function(x,name){
  tmp <- read.csv(x)
  assign(name, tmp, pos = ".GlobalEnv")

}

Note that I have to specify this assignment should happen in the global environment. If that's not the behaviour you want, change the pos argument to a suitable value. More information on ?assign and ?search for how the search path is constructed.

On a sidenote: NEVER EVER use T and F as short for TRUE and FALSE:

> isTRUE(T)
[1] TRUE
> T <- 0
> isTRUE(T)
[1] FALSE

In the old days I broke packages where the author was stupid enough to use T and F doing exactly this. Luckily that's not allowed any longer in CRAN packages.

Upvotes: 3

Related Questions