1

I'd like to create multiple data frames with a for loop, and add a column and remove others from each of the new data frames. The original dataset looks something like this:

Site  Count1  Count2  Count3  Count4  Count5  Count6  Count7  Count8  Count9  Habitat
  1     0       0       0       0       1       0        2       0       1     Forest
  2     1       2       3       0       0       2        0       1       0     Field
  3     2       0       0       1       1       1        0       2       0     Field

Essentially I want to create a new data frame for each count column, so here I would have nine new dataframes that look like this:

df.1:

Site TotCount Habitat
  1     0       Forest
  2     1       Field
  3     2       Field

df.2:

Site TotCount Habitat
  1     0       Forest
  2     2       Field
  3     0       Field

And so on.

This creates the frames I need:

for (z in 1:9){       
  assign(paste("df",z,sep="."),orig_data)
}

I can't figure out the second step - carry the appropriate count into each new data frame along with the habitat column (and others not shown above). I am hoping to keep this automated as it's possible there could be many more than 9 counts.

2 Answers 2

4

This will create a list of nine data.frames which is (trust me) a much better thing than creating nine variables into your global environment:

data.list <- lapply(1:9, function(i) {
  setNames(data[c("Site", paste0("Count", i), "Habitat")],
           c("Site", "TotCount", "Habitat"))
})

Instead of df.1, you can access the first data.frame by doing data.list[[1]]. Also, if you want to apply a function to all data.frames (i.e. a loop), have a look at lapply or sapply.

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

Comments

0

This will put the df.x objects into the global environment.

# example data
df <- data.frame(Site = 1:3, 
                 Count1 = 0:2, 
                 Count2 = c(0,2,0), 
                 Count3 = c(0,3,0), 
                 Habitat = c("Forest", "Field", "Field") 
                 )

A function to do the work:

countSplit_2df <- function(DF){
    CountCols <- grep("Count", names(DF))
    HabCol <- grep("Habitat", names(DF))
    for (z in CountCols) {
        assign(paste("df", z, sep="."), 
               rbind(df[,c(1, z, HabCol)]),
               envir = .GlobalEnv)
    }
}

Now apply it:

countSplit_2df(df)

And ls() and you'll see

> ls()
[1] "countSplit_2df" "df"             "df.2"           "df.3"          
[5] "df.4" 

Note this is not exactly as you asked for, as i've named them using the column number from the grep.

To complete the answer, someone needs to get the right way of selecting the text after "Count" in the grep -- you'd then use that to label the df.x objects. I couldn't get it to work.

Comments

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.