0

I am trying to use a for loop to multiple create dataframes. The original code works fine for a single run (without the for loop).

object<- c(1,2,3)

for (i in 1:length(object)) {

df1<- SomeFunction1(object[i])
df2<- SomeFunction2(object[i])
df3<- SomeFunction3(object[i])

N.rows <- length(object)
combined <- vector("list", N.rows)

combined[i]<-list(rbind(df1,df2,df3))

When I do this I get combined[3] but not the outputs from the two other variables in my object. I have toyed around with it and managed to get as a result combined1, but again not a list with combined1, combined[2], and combined[3].

UPDATE: I was asked for the concrete example and expected output.

I'm basically taking three CSV files of county census data but organized differently (two with years as rows, and one with years as columns), transforming the data into a consistent format by county and then combining the files.

enter image description here

The above image is the result of View(combine). [[2]] is just what I want, but nothing is stored in [1].

This is the code that I used to get to it:

pop1990.2000 <- read.csv("1990-2000 Census Pop.csv", 
                     stringsAsFactors = FALSE)
pop2000.2010 <- read.csv("2000-2010 Census Pop.csv", 
                     stringsAsFactors = FALSE)
pop2010.2019 <- read.csv("2010-2019 Census Pop.csv", 
                     stringsAsFactors = FALSE)


#Adding Total column "Population"
pop1990.2000$Population <- (rowSums(pop1990.2000) - 
                   pop1990.2000$Year - 
                   pop1990.2000$FIPS.Code)

#Combining State and County FIPS codes "FIPS.Code"
pop2000.2010$FIPS.Code <- (pop2000.2010$STATE*1000+
                         pop2000.2010$COUNTY)

pop2010.2019$FIPS.Code <- (pop2010.2019$STATE*1000+
                         pop2010.2019$COUNTY)

my_counties<-c(1125, 1127)

for (i in 1:length(my_counties)) {


#Selecting Pop data for County 1125 for 1990-2000
newdata <- pop1990.2000[ which(pop1990.2000$FIPS.Code==my_counties[i]), ]
newdata2000v1 <- as.data.frame(cbind(Year=newdata$Year, 
                                 Population=newdata$Pop))

#Adding FIPs Code
newdata2000v1$FIPS.Code<-my_counties[i]


#Merging County Name by FIPS.Code
pop2000.2010.c.fips <- pop2000.2010 %>%
  select(FIPS.Code, CTYNAME)

pop2000.2010.c.fips$County<-pop2000.2010.c.fips$CTYNAME

newdata2000v1 <- newdata2000v1 %>%  
  mutate(FIPS.Code = as.numeric(FIPS.Code))

newdata2000 <- left_join(newdata2000v1, 
                     pop2000.2010.c.fips, 
                     by = "FIPS.Code")

newdata2000<-newdata2000 %>% select(County, FIPS.Code, Year, Population)


#Selecting Pop data for County 1125 for 2000-2010
newdata2 <- pop2000.2010[ which(pop2000.2010$FIPS.Code==my_counties[i]), ]

newdata2010 <- cbind("2000"=newdata2$ESTIMATESBASE2000, 
                 "2001"=newdata2$POPESTIMATE2001, 
                 "2002"=newdata2$POPESTIMATE2002, 
                 "2003"=newdata2$POPESTIMATE2003, 
                 "2004"=newdata2$POPESTIMATE2004, 
                 "2005"=newdata2$POPESTIMATE2005, 
                 "2006"=newdata2$POPESTIMATE2006, 
                 "2007"=newdata2$POPESTIMATE2007, 
                 "2008"=newdata2$POPESTIMATE2008, 
                 "2009"=newdata2$POPESTIMATE2009)

newdata2010<-as.data.frame(t(newdata2010))

newdata2010$County<-newdata2$CTYNAME
newdata2010$FIPS.Code<-newdata2$FIPS.Code

newdata2010$Year<-c(rownames(newdata2010))

names(newdata2010)[names(newdata2010) == 'V1'] <- 'Population'

newdata2010<-newdata2010 %>% select(County, FIPS.Code, Year, Population)



#Selecting Pop data for County 1125 for 2010-2019
newdata3 <- pop2010.2019[ which(pop2010.2019$FIPS.Code==my_counties[i]), ]
newdata2019 <- cbind(Year=newdata3$Year, 
                 "2010"=newdata3$CENSUS2010POP, 
                 "2011"=newdata3$POPESTIMATE2011, 
                 "2012"=newdata3$POPESTIMATE2012, 
                 "2013"=newdata3$POPESTIMATE2013, 
                 "2014"=newdata3$POPESTIMATE2014, 
                 "2015"=newdata3$POPESTIMATE2015, 
                 "2016"=newdata3$POPESTIMATE2016, 
                 "2017"=newdata3$POPESTIMATE2017, 
                 "2018"=newdata3$POPESTIMATE2018,
                 "2019"=newdata3$POPESTIMATE2019)


newdata2019<-as.data.frame(t(newdata2019))

newdata2019$County<-newdata3$CTYNAME
newdata2019$FIPS.Code<-newdata3$FIPS.Code

newdata2019$Year<-c(rownames(newdata2019))

names(newdata2019)[names(newdata2019) == 'V1'] <- 'Population'

newdata2019<-newdata2019 %>% select(County, FIPS.Code, Year, Population)



N.rows <- length(my_counties)
combined <- vector("list", N.rows)
combined[i]<-list(rbind(newdata2000,newdata2010,newdata2019))
4
  • are you tied to using a loop or would you consider lapply? Commented Jun 18, 2020 at 19:30
  • 1
    Hi Michael, welcome to Stack Overflow. I think we will likely need additional information to answer your question. I suspect your real object is not a simple integer vector, or else you wouldn't be calling the results df1. Can you also provide a more concrete example of SomeFunction1 as well as some expected output? Thanks! Commented Jun 18, 2020 at 19:34
  • Thanks @IanCampbell. Just recently joined and finding it immensely useful. 'object' is in fact just three numbers, but the SomeFunction is a black box because I thought it wasn't relevant. Ultimately what I am struggling with is if a set of code produces an object in a loop, how do I save each new object[i]. From what I have seen it seems as a list is the way to go but struggling to make that work. I'll add the concrete example and expected output although it is really messy. Commented Jun 18, 2020 at 23:09
  • Object assignment within a function only occurs inside the environment of the function. A potentially dangerous, but quick work around may be the <<- operator. This assigns values in the global environment. So you might try combined[i] <<- list(rbind(df1,df2,df3)) Commented Jun 18, 2020 at 23:13

1 Answer 1

2

The problem is that you are re-specifying the creation of the combined object. I am not sure what exactly your var1 is, but, possibly the following should work:

object<- c(1,2,3)
N.rows <- length(var1)
combined <- vector("list", N.rows)

for (i in 1:length(object)) {

     df1<- SomeFunction1(object[i])
     df2<- SomeFunction2(object[i])
     df3<- SomeFunction3(object[i])         

combined[i]<-list(rbind(df1,df2,df3))
}

Alternatively, using lapply:

object<- c(1,2,3)
combined<-lapply(object, function(i){

     df1<- SomeFunction1(object[i])
     df2<- SomeFunction2(object[i])
     df3<- SomeFunction3(object[i])         

     list(rbind(df1,df2,df3))
}

But this will deliver the list of length 3 (with three lists with df1,df2 and df3), not the length defined by the length of var1...

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

1 Comment

Thanks @hamagust! I moved the code you showed outside the loop and that did the trick. N.rows <- length(var1) combined <- vector("list", N.rows) I tried to upvote but I don't have enough reputation points yet.

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.