Hi all, I am a beginner R user and need some help with a simple loop function. Currently, I have seven datasets (TOWER1,TOWER2...TOWER7) that are all in the same format (same # of col and headers). I am trying to add a new column (factor) to each dataset that simply identifies the dataset. Ultimately, I would like to merge all 7 datasets and need that column to identify what rows came from what dataset. Using the code below, I get the error message "Error in rep(i, nrow(TOWER.i)) : invalid 'times' argument" but it doesn't make sense to me since nrow should give an integer value. Any help will be really appreciated. TOWERS<-c("TOWER1","TOWER2","TOWER3","TOWER4","TOWER5","TOWER6","TOWER7") for(i in 1:7){ TOWER.i<-TOWERS[i] TOWER<-rep(i,nrow(TOWER.i)) TOWER.i<-cbind(TOWER.i[1:2],TOWER, TOWER.i[2:length(TOWER.i)]) } -- View this message in context: http://r.789695.n4.nabble.com/Loop-Help-tp4630555.html Sent from the R help mailing list archive at Nabble.com.
First, what was going wrong: #this creates a character vector, not an object containing your data sets TOWERS <- c("TOWER1","TOWER2","TOWER3","TOWER4","TOWER5","TOWER6","TOWER7") for(i in 1:7){ # this creates a variable named "TOWER.i" (not "TOWER.1, TOWER.2, ..., TOWER.7) # which will get overwritten each time through the loop TOWER.i <- TOWERS[i] # This is what causes your error, as TOWER.i is a string ("TOWER1", "TOWER2", ...), and hence nrow(TOWER.i) return NULL ? ?TOWER <- rep(i,nrow(TOWER.i)) # if you got to here, you would have got more errors as TOWER.i is cannot be subsetted # (it is a string, not a 'dataset' with columns) ? ?TOWER.i <- cbind(TOWER.i[1:2], TOWER, TOWER.i[2:length(TOWER.i)]) } # Note that to create variables like 'TOWER.1', ..., you would have to say something like assign(paste('TOWER', i, sep='.'), TOWERS[[i]]) # inside the loop. However, this is not necessary here and you would keep needing to # access the variable with similar ugliness. Here is the way I might approach this: TOWERS <- list(TOWER1,TOWER2,TOWER3,TOWER4,TOWER5,TOWER6,TOWER7) # create a list of things that look like what you wanted TOWERS.i to look like # (still with column two repeated TOWERS.modified <- mapply(function(x, i) cbind(x[,1:2], i, x[,2:ncol(x)]), TOWERS, 1:length(TOWERS), SIMPLIFY=F) # you can then 'merge' them (though that term would mean something else to most # R programmers - see ?merge) with: TOWERS.combined <- do.call(rbind, TOWERS.modified) #Now what I would actually do is: TOWERS.combined <- do.call(rbind, lapply(1:7, function(i) { x <- get(paste('TOWER', i, sep='')) cbind(x[,1:2], i, x[,2:ncol(x)]) })) Hopefully that makes sense, if not I can provide more explanation, but please try ?do.call, ?get, ?lapply and ?mapply first Simon On Sat, May 19, 2012 at 9:14 AM, bdossman <bdossman at gmail.com> wrote:> Hi all, > > I am a beginner R user and need some help with a simple loop function. > > Currently, I have seven datasets (TOWER1,TOWER2...TOWER7) that are all in > the same format (same # of col and headers). I am trying to add a new column > (factor) to each dataset that simply identifies the dataset. Ultimately, I > would like to merge all 7 datasets and need that column to identify what > rows came from what dataset. > > Using the code below, I get the error message "Error in rep(i, > nrow(TOWER.i)) : invalid 'times' argument" but it doesn't make sense to me > since nrow should give an integer value. Any help will be really > appreciated. > > TOWERS<-c("TOWER1","TOWER2","TOWER3","TOWER4","TOWER5","TOWER6","TOWER7") > > for(i in 1:7){ > ? ? ? ?TOWER.i<-TOWERS[i] > ? ? ? ?TOWER<-rep(i,nrow(TOWER.i)) > ? ? ? ?TOWER.i<-cbind(TOWER.i[1:2],TOWER, TOWER.i[2:length(TOWER.i)]) > } > > -- > View this message in context: http://r.789695.n4.nabble.com/Loop-Help-tp4630555.html > Sent from the R help mailing list archive at Nabble.com. > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
Hello, The error is that you are trying to use the number of rows of a character string. TOWERS[1], TOWERS[2], etc, are not data frames. Use a print statement before the line that throws the error to check it. Your problem can be solved along the lines of what follows. Note that I've put all data frames in a list, it's better to have them kept like that, it makes everything else simpler. # Create a list with some made up data.frames towers <- list(TOWER1=data.frame(A=letters[1:4], X=rnorm(4)), TOWER2=data.frame(A=LETTERS[1:6], X=runif(6))) towers # In your case this is from TOWER1 to TOWER7 TOWERS <- names(towers) towers.with.id <- lapply(TOWERS, function(i){ towers[[ i ]]$Tower <- factor(i) towers[[ i ]]}) (Use something other than 'towers.with.id', this is just an example.) #names(towers.with.id) <- TOWERS # (*) See below towers.with.id do.call(rbind, towers.with.id) (*) Try to run these last three instructions with the marked line commented/uncommented. It's better to uncomment, maybe after rbind. You'll later be able to access the list elements with a syntax like towers.with.id[[ "TOWER2" ]] # full data.frame 2 towers.with.id[[ TOWERS[2] ]]$A # just that column towers.with.id[[ "TOWER2" ]]$A[3] # third element of that column If you do.call/rbind before, to solve the rbind-ed data.frame's row names use rownames(result) <- seq.int(nrow(result)) where 'result' is the result of do.call. Hope this helps, Rui Barradas Em 19-05-2012 11:00, r-help-request at r-project.org escreveu:> Date: Fri, 18 May 2012 16:14:08 -0700 (PDT) > From: bdossman<bdossman at gmail.com> > To:r-help at r-project.org > Subject: [R] Loop Help > Message-ID:<1337382848213-4630555.post at n4.nabble.com> > Content-Type: text/plain; charset=us-ascii > > Hi all, > > I am a beginner R user and need some help with a simple loop function. > > Currently, I have seven datasets (TOWER1,TOWER2...TOWER7) that are all in > the same format (same # of col and headers). I am trying to add a new column > (factor) to each dataset that simply identifies the dataset. Ultimately, I > would like to merge all 7 datasets and need that column to identify what > rows came from what dataset. > > Using the code below, I get the error message "Error in rep(i, > nrow(TOWER.i)) : invalid 'times' argument" but it doesn't make sense to me > since nrow should give an integer value. Any help will be really > appreciated. > > TOWERS<-c("TOWER1","TOWER2","TOWER3","TOWER4","TOWER5","TOWER6","TOWER7") > > for(i in 1:7){ > TOWER.i<-TOWERS[i] > TOWER<-rep(i,nrow(TOWER.i)) > TOWER.i<-cbind(TOWER.i[1:2],TOWER, TOWER.i[2:length(TOWER.i)]) > }
Hello all, I'm new here and new to R, but I have to admit I'm learning rather fast. Right now I need to write a loop, and I don't seem to think I'm doing it properly, judging by the errors I get! What I need to do is to insert my data (csv-table) into a variable, and take snapshots of my data (it's longtitudinal) and they 'play' with the snapshot. To give you an example: # I Load tnet the library I need library(tnet) # I Load my data net <- read.table("data.txt") # Check if net is tnet net <- as.tnet(net, type="longitudinal tnet") # And slice the data getting new variables for every day net.101031 <- as.static.tnet(net[net[,"t"]<=as.POSIXlt("2010-10-31 00:00:00"),]) # Then get the degree of the sliced network degree_w(net.101031) # and the mean of each column in the data.frame apply(net.101031, 2, mean) Now the problem is that there are way too many "days" to do it manually and I need to wrap this part: net.101031 <- as.static.tnet(net[net[,"t"]<=as.POSIXlt("2010-10-31 00:00:00"),]) degree_w(net.101031) apply(net.101031, 2, mean) in a loop, and print the results. But... Can someone please help me...???? Thank you so much in advance! -- View this message in context: http://r.789695.n4.nabble.com/Loop-Help-tp4633558.html Sent from the R help mailing list archive at Nabble.com.
Hi, Do you mean printing the results of degree_w(net.101031) and apply(net.101031, 2, mean) in a loop? see ?print to print the results and ?cat as a suporting function. For instance see the toy example below for (i in 1:5){ print('------------------------------------') cat("model",i,"\n") print(summary(lm(rnorm(10,0,1)~rnorm(10,0,2)))) } Hope this helps Ozgur -- View this message in context: http://r.789695.n4.nabble.com/Loop-Help-tp4633558p4633572.html Sent from the R help mailing list archive at Nabble.com.
@angel, You can try append option in write.table for e.g. for(i in 1:20) write.table(i,"out.txt",append=T,sep="\t",row.names=F,col.names=F) This will help you save your all results by writing each results on subsequent rows. Hope this helps Ozgur>Hello Jim >thank you so much for your response. >When I use write.csv, on the csv file is saved only the last loop >So when I write>results.matrix <- apply(degree_w(net.static[[i]]), 2, mean) >write.csv(results.matrix, file = "results.csv")>instead of getting a 550 line document with all loop results, I only getthe last one!>Could you please help me? >Thank you so much in advance-- View this message in context: http://r.789695.n4.nabble.com/Loop-Help-tp4633558p4633722.html Sent from the R help mailing list archive at Nabble.com.