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
  • 97
  • 6
  • 1
    It seems likely that you should use `[[` or `[` ; https://stackoverflow.com/questions/18222286/dynamically-select-data-frame-columns-using-and-a-character-value and https://stackoverflow.com/questions/2641653/pass-a-data-frame-column-name-to-a-function – user20650 Sep 06 '20 at 14:44
  • It is not clear to me what you want to do? If you can post your code, I may be able to help. – Liman Sep 06 '20 at 14:46
  • Is that what you want: `paste("iris$", iris$Sepal.Length, sep = "")`? – Chris Ruehlemann Sep 06 '20 at 14:49
  • Once you have the string ColName = "iris$Spel.Length", try `get(ColName)` – G5W Sep 06 '20 at 14:50
  • Here is the code: ``` 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 Sep 06 '20 at 16:20
  • What is the output you expect from that function? – Aaron Montgomery Sep 06 '20 at 17:48
  • I am expecting frequency distribution table of each column in the data frame – azmath Sep 06 '20 at 20:14

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,387
  • 8
  • 11