0

I want to concatenate iris$SepalLength, so I can use that in a function to get the Sepal Length column from iris data frame. But when I use paste function paste("iris$", colnames(iris[3])), the result is as characters (with quotes), as "iris$SepalLength". I need the result not as a character. I have tried noquotes(), as.datafram() etc but it doesn't work.

freq <- function(y) {
  for (i in iris) {
    count <-1
    y <- paste0("iris$",colnames(iris[count]))
    data.frame(as.list(y))
    print(y)
    span = seq(min(y),max(y), by = 1)
    freq = cut(y, breaks = span, right = FALSE)
    table(freq)
    count = count +1
  }
}
freq(1)
azmath
  • 77
  • 5

1 Answers1

0

The crux of your problem isn't making that object not be a string, it's convincing R to do what you want with the string. You can do this with, e.g., eval(parse(text = foo)). Isolating out a small working example:

y <- "iris$Sepal.Length"
data.frame(as.list(y))                      # does not display iris$Sepal.Length
data.frame(as.list(eval(parse(text = y))))  # DOES display iris.$Sepal.Length

That said, I wanted to point out some issues with your function:

  1. The input variable appears to not do anything (because it is immediately overwritten), which may not have been intended.
  2. The for loop seems broken, since it resets count to 1 on each pass, which I think you didn't mean. Relatedly, it iterates over all i in iris, but then it doesn't use i in any meaningful way other than to keep a count. Instead, you could do something like for(count in 1 : length(iris) which would establish the count variable and iterate it for you as well.
  3. It's generally better to avoid for loops in R entirely; there's a host of families available for doing functions to (e.g.) every column of a data frame. As a very simple version of this, something like apply(iris, 2, table) will apply the table function along margin 2 (the columns) of iris and, in this case, place the results in a list. The idea would be to build your function to do what you want to a single vector, then pass each vector through the function with something from the apply() family. For instance:
cleantable <- function(x) {
  myspan = seq(min(x), max(x))  # if unspecified, by = 1
  myfreq = cut(x, breaks = myspan, right = FALSE)
  table(myfreq)
}

apply(iris[1:4], 2, cleantable)  # can only use first 4 columns since 5th isn't numeric

would do what I think you were trying to do on the first 4 columns of iris. This way of programming will be generally more readable and less prone to mistakes.

Aaron Montgomery
  • 1,332
  • 6
  • 10