0

I am having an issue using a user-defined function within a for loop, as shown in the code below. It seems to be an issue with the way I'm trying to input an index into the function, as I get the below message whenever I try to run it.

Error: $ operator is invalid for atomic vectors

However, the function runs fine on its own. It returns the correct result when I use it with one of the variables outside the loop.

Essentially, what I'm trying to do is:

  1. run the function on all variables that store the data I've imported
  2. store the data generated by the function in that same variable, overwriting the original data.

It could be that my whole way of going about this is wrong. Is it even possible to call variables using a list of their names? Example input data is imported into R using read.delim and looks like this:

Data Screenshot

There are 1,400 or so files being read in.

## Import files:
temp = list.files(pattern="*.csv")  #Filenames from working directory       
for (i in 1:length(temp)) {
    #Clean data to include only RGB
    assign(temp[i], read.delim(temp[i],sep=";", header = T, nrows = 6)) 
}

allvars <- ls(all.names = T) #List all variables

#Find RGB classes and name
getClasses <- function(variable) {  
    red <- variable$R[3:5]
    green <- variable$G[3:5]
    blue <- variable$B[3:5]
    classes <- data.frame(red, green, blue)
    print(classes)
}

#This is where the problem happens:
for (i in 1:length(allvars)) {
    #Apply getClasses function to current variable and store new data
    assign(allvars[i], getClasses(allvars[i]))  
}
#Error: $ operator is invalid for atomic vectors
Parfait
  • 104,375
  • 17
  • 94
  • 125
Anna
  • 1
  • 1
  • allvars is just a list ... try to type "allvars$R" in your R console, and see what happen .. – MrSmithGoesToWashington Jan 19 '18 at 15:31
  • 4
    Why are you trying to loop over all variables in your global namespace? Are you *sure* that it only contains the variables that you are interested in? Code that makes sweeping assumptions about that namespace is fragile at best. – John Coleman Jan 19 '18 at 15:33
  • 1
    `allvars[i]` is a string; `getClasses <- function(variable) {` is passed this string; `variable$R[3:5]` is trying to access `string$R[3:5]`, which doesn't make sense. Try `get(variable)$R[3:5]` to access the data indicated by the string; Update the rest of your color vars `green, blue` – CPak Jan 19 '18 at 15:35
  • 2
    To add a little more exposition to the point made by @CPak : `ls(all.names = T)` returns a character vector, where each element gives the name of an object in the global environment. When you access `allvars[i]`, you get a character vector of length one with the *name* of an object, you do not get the object itself. That's why you need `get()` (see `help("get")`). I also can't stress enough though that this is probably a bad idea for the reasons stated by John Coleman. – duckmayr Jan 19 '18 at 15:43
  • 4
    You'd be much better off putting your data in a list. [See this answer for discussion and examples](https://stackoverflow.com/questions/17499013/how-do-i-make-a-list-of-data-frames/24376207#24376207). – Gregor Thomas Jan 19 '18 at 15:44

0 Answers0