6

I have a list of variable names and I want to use the strings from the list to access columns in data frames

list<-list("Var1", "Var2", "Var3")
df1 <- data.frame("Var1" = 1:2, "Var2" = c(21,15), "Var3" = c(10,9))
df2<- data.frame("Var1" = 1, "Var2" = 16, "Var3" = 8)

I have 2 uneven data frames and I want to create a new column by doing some basic maths

df1$Var4<-df1$Var1 + df2$Var1

Var4
2
3

But i want to be able to call the column names i'm adding together by refering to the list of variables names I have, I have tried the two following pieces of code by neither worked

df1$Var4<- df1$List[1]+df1$list[1]

and 

Z<-list[1]
df1$Var4 <- df1$Z + df2$Z

I don't want to hard code the column names because this will be creating a function to be used across data frames where the variable names will change

Any help would be much appreciated

Dave Matteo
  • 117
  • 4
  • @Henrik I think it's related, but not really a dupe as you cannot completely answer this question based on the linked one. – tmfmnk Jul 22 '20 at 13:45
  • 1
    You may be right @tmfmnk. But I think it's worth linking to, because the _core problem_ of the question is answered in the canonical post. Cheers. – Henrik Jul 22 '20 at 13:53

5 Answers5

7

Try this:

list<-list("Var1", "Var2", "Var3")
df1 <- data.frame("Var1" = 1:2, "Var2" = c(21,15), "Var3" = c(10,9))
df2<- data.frame("Var1" = 1, "Var2" = 16, "Var3" = 8)
#Sum
df1$Var4<- df1[,list[[1]]]+df2[,list[[1]]]

  Var1 Var2 Var3 Var4
1    1   21   10    2
2    2   15    9    3
Duck
  • 39,058
  • 13
  • 42
  • 84
3

To follow up with the reasoning to Duck's obviously correct answer, your approach isn't working for two reasons:

  1. The $ operator does "not allow computed indices", so you can't pass a character vector to it. See help(`$`).
`$`(df1,"Var1")
#[1] 1 2

`$`(df1,list[[1]])
#Error in df1$list[[1]] : invalid subscript type 'language'
  1. You were trying to subset df1 with a list. You need a character vector.
list[1]
#[[1]]
#[1] "Var1"

class(list[1])
#[1] "list"

The [[ operator selects an individual element from a list. In this case, the character vector you needed.

list[[1]]
#[1] "Var1"

class(list[[1]])
#[1] "character"
Ian Campbell
  • 23,484
  • 14
  • 36
  • 57
2

You can try the code below

df1$Var4 <- Map(`+`,df1,df2)[[lst[[1]]]]

such that

> df1
  Var1 Var2 Var3 Var4
1    1   21   10    2
2    2   15    9    3
ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81
2

One option using dplyr could be:

df1 %>%
 mutate(Var4 = c_across(lst[[1]]) + pull(df2, lst[[1]]))

  Var1 Var2 Var3 Var4
1    1   21   10    2
2    2   15    9    3

Or with the addition of purrr:

df1 %>%
 mutate(Var4 = c_across(pluck(lst, 1)) + pull(df2, pluck(lst, 1)))
tmfmnk
  • 38,881
  • 4
  • 47
  • 67
1

You can simply use strings directly to access column names:

list<-list("Var1", "Var2", "Var3")
df1 <- data.frame("Var1" = 1:2, "Var2" = c(21,15), "Var3" = c(10,9))
df2<- data.frame("Var1" = 1, "Var2" = 16, "Var3" = 8)
df1$Var4 <- df1[[list[[1]]]] + df2[[list[[1]]]]

Output

> df1
  Var1 Var2 Var3 Var4
1    1   21   10    2
2    2   15    9    3
slava-kohut
  • 4,203
  • 1
  • 7
  • 24