bretauv
bretauv

Reputation: 8555

R: "$ operator is invalid for atomic vectors"

I would like to make a function returning a particular column of a dataframe since I have several dataframes whose names vary of just one digit. For example, I have:

mtcars1 <- data.frame(name1 = mtcars[5, 1], name2 = c(1, 8, 2, 9, 9))
mtcars2 <- data.frame(name1 = mtcars[5, 1], name2 = c(1, 8, 3, 9, 9))

foo <- function(i){
  x <- paste0("mtcars", i)$name2
  return(x)
}

foo(1) is supposed to return 1 8 2 9 9 and foo2 is supposed to return 1 8 3 9 9

The problem is that I have the error:

Error in paste0("mtcars", i)$name2 : $ operator is invalid for atomic vectors

This is surely a straightforward question but how can I do it?

Upvotes: 0

Views: 3729

Answers (2)

tushaR
tushaR

Reputation: 3116

You can also use eval():

mtcars1 <- data.frame(name1 = mtcars[5, 1], name2 = c(1, 8, 2, 9, 9))
mtcars2 <- data.frame(name1 = mtcars[5, 1], name2 = c(1, 8, 3, 9, 9))

foo <- function(i){
      x <- eval(expr = parse(text=paste0("mtcars", i,"$name2")))
      return(x)
}

#>foo(1)
#[1] 1 8 2 9 9
#>foo(2)
#[1] 1 8 3 9 9

Upvotes: 1

Colin FAY
Colin FAY

Reputation: 5109

The issue is that paste0("mtcars", i)$name2 returns a character vector, which can't be subset by $.

You can use get to do what you want:

> mtcars1 <- data.frame(name1 = mtcars[5, 1], name2 = c(1, 8, 2, 9, 9))
> mtcars2 <- data.frame(name1 = mtcars[5, 1], name2 = c(1, 8, 3, 9, 9))
> 
> foo <- function(i){
+   x <- get(paste0("mtcars", i))$name2
+   return(x)
+ }
> foo(1)
[1] 1 8 2 9 9
> foo(2)
[1] 1 8 3 9 9

Upvotes: 3

Related Questions