0

If I am working with dataframes in a loop, how can I use a variable data frame name (and additionally, variable column names) to access data frame contents?

dfnames <- c("df1","df2")

df1 <- df2 <- data.frame(X = sample(1:10),Y = sample(c("yes", "no"), 10, replace = TRUE))

for (i in seq_along(dfnames)){
    curr.dfname <- dfnames[i]

    #how can I do this:
    curr.dfname$X <- 42:52

    #...this
    dfnames[i]$X <- 42:52

    #or even this doubly variable call
    for (j in 1_seq_along(colnames(curr.dfname)){
        curr.dfname$[colnames(temp[j])] <- 42:52
    }
}
3
  • Put the two data frames in a named list. Commented Mar 2, 2015 at 4:26
  • @joran, like, dflist<-c(df1,df2), then access it like dflist[i]$X<-42 ? trouble is those dfs are created in that loop. I could do a second set though if needs be. Commented Mar 2, 2015 at 4:30
  • No. list(df1 = df1, df2 = df2), and you can use [[ to access either by name or position. You should read up on lists. Commented Mar 2, 2015 at 4:34

1 Answer 1

6

You can use get() to return a variable reference based on a string of its name:

> x <- 1:10
> get("x")
[1]  1  2  3  4  5  6  7  8  9 10

So, yes, you could iterate through dfnames like:

dfnames <- c("df1","df2")
df1 <- df2 <- data.frame(X = sample(1:10), Y = sample(c("yes", "no"), 10, replace = TRUE))

for (cur.dfname in dfnames)
{
    cur.df <- get(cur.dfname)

    # for a fixed column name
    cur.df$X <- 42:52

    # iterating through column names as well
    for (j in colnames(cur.df))
    {
        cur.df[, j] <- 42:52
    }
}

I really think that this is gonna be a painful approach, though. As the commenters say, if you can get the data frames into a list and then iterate through that, it'll probably perform better and be more readable. Unfortunately, get() isn't vectorised as far as I'm aware, so if you only have a string list of data frame names, you'll have to iterate through that to get a data frame list:

# build data frame list
df.list <- list()
for (i in 1:length(dfnames))
{
    df.list[[i]] <- get(dfnames[i])
}

# iterate through data frames
for (cur.df in df.list)
{
    cur.df$X <- 42:52
}

Hope that helps!

2018 Update: I probably wouldn't do something like this anymore. Instead, I'd put the data frames in a list and then use purrr:map(), or, the base equivalent, lapply():

library(tidyverse)

stuff_to_do = function(mydata) {
  mydata$somecol = 42:52
            # … anything else I want to do to the current data frame
  mydata    # return it  
}

df_list = list(df1, df2)
map(df_list, stuff_to_do)

This brings back a list of modified data frames (although you can use variants of map(), map_dfr() and map_dfc(), to automatically bind the list of processed data frames row-wise or column-wise respectively. The former uses column names to join, rather than column positions, and it can also add an ID column using the .id argument and the names of the input list. So it comes with some nice added functionality over lapply()!

Sign up to request clarification or add additional context in comments.

7 Comments

This was a helpful answer! How do I unlist the dataframes that were manipulated in the function? (Note: some of the dataframes themselves contain lists, so list2env(cur.df ,.GlobalEnv) is going to be problematic.)
I definitely wouldn't do this anymore! Gimme half an hour to find some breakfast and I'll give you a more modern answer?
That would be amazing! This is 100% applicable to what I am doing right now :)
I've popped it on the end of my answer :)
Thanks so much! So, many of the columns in the dataframe are unique and need to be processed separately - but some of the transformations of variables are the same, which is why I'm trying to write this function. I am struggling to extract the df in a list individually - i.e. get back to df1, df2` being separate. Do you have a sense of how to do that?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.