[R] R for loop nested?
Kenn Konstabel
lebatsnok at gmail.com
Tue Oct 25 21:13:45 CEST 2011
Hi there,
I'm adding a very small bit of something utterly useless to Michael's
response. When you start wondering why your code doesn't work the way
you expect, making it as simple as possible might be the first step.
For example, the following piece of code ...
TRUE
... is simpler than ...
!!!!TRUE
... and this, in turn, is simpler than ...
!(!(!(!(TRUE))))
... but they all result in the same value.
A couple of ideas how to make your code easier to read:
if (((length(name$Behavior))) %% 2 != 0) { something }
Here you have an extra pair of parentheses that could just as well be deleted:
if ((length(name$Behavior)) %% 2 != 0) { something }
But length() of a variable in a data frame is just nrow() of that data
frame so you could simplify this further to ...
if (nrow(name) %% 2 != 0) { something }
And this one ...
if (y %% 2 == 0) {next} else
{q<-c(q, (c(name$Time[y]:name$Time[y +1])))}
... is particularly tough considering that you might just as well write
if (y %% 2 != 0) q<-c(q, name$Time[y]:name$Time[y +1])
... or, if you like them a lot, ...
if ((((y))) %% (((2))) == (((0)))) {next} else
{q<-c((((q))), (c((((name$Time[y]))):(((name$Time[y
+(((1)))]))))))}
... would also do with some extra aesthetic pleasure.
> name = read.table(file.choose(),header=F) # opening a data file
> colnames(name)<-c("Time", "Behavior")
> name = data.frame(name$Behavior, name$Time)
> colnames(name)<-c("Behavior", "Time")
> name<-name[name$Time < 3600, ];
I don't get it. The result of read.table is a data frame, so you may
use names instead of colnames, and the 3rd and 4th lines seem to be
unnecessary. If you just want to switch the first and the second
variable, then X[,2:1] would do it. So instead of that you could
write:
X <- read.table(file.choose(),header=FALSE)[,2:1] # the name "name"
sounds confusing
names(X) <- c("Behavior", "Time")
X <- subset(X, Time < 3600)
... (the following single line would also do but is uglier)
X <- subset(structure(read.table(file.choose(), header=FALSE)[,2:1],
.Names=c("Behavior", "Time")), Time < 3600)
And it may help giving your objects some meaningful names. For example,
a <- list.files()
is fine but alternative (and some might say, better understandable at
first look) names to `a` could be, e.g., `files` or `MYFILES` or
`list.of.files`. And ....
name<- read.table(i,header=F)
... again, you may name anything in whatever way but to call a data
table a `name` may be confusing to some readers. And saying that
xx<- c()
... is just another way of saying that xx <- NULL . NULL is clearer
than c() as it makes your intention (to make an empty object and then
start adding something to it) more obvious. Besides, NULL is quicker
and more efficient.
Sorry for not giving any useful advice, it's late here.
Best regards,
Kenn Konstabel
On Tue, Oct 25, 2011 at 3:19 PM, Delia Shelton <delsshel at indiana.edu> wrote:
> Hi,
>
> I'm trying to execute the same R code on multiple data frames listed in a single directory. The code works fine if I use the code
> (below) for each file. However, I have several files and it becomes
> tedious to run each one, name it and then aggregate into a single
> dataframe.
>
> Name
> 0.0 1
> 21.15 2
> 2400.26 1
> 3222.14 2
>
>
> name = read.table(file.choose(),header=F) # opening a data file
> colnames(name)<-c("Time", "Behavior")
> name = data.frame(name$Behavior, name$Time)
> colnames(name)<-c("Behavior", "Time")
> name<-name[name$Time < 3600, ];
>
>
> x<-seq(0,3600, by = 60) # total time partition by time which is 60
>
> if (tail(name$Behavior, 1) == 1) {name<-rbind(name, c(4, 3600))} else
> {name<-rbind(name, c(1, 3600))}
>
> if (((length(name$Behavior))) %% 2 != 0)
> {name <-name[-c(length(name$Behavior)), -c(length(name$Behavior))]}
>
> q<-c()
> for (y in (1: (length(name$Behavior))))
> {
> if (y %% 2 == 0) {next} else
> {q<-c(q, (c(name$Time[y]:name$Time[y +1])))}
> }
>
> b<-table(cut(q,x))
>
> sum(b)
>
>
> So, I tried to nest a for loop within another(code
> below). It solved the problem of selecting each data file. However, a
> problem was incurred with the second loop. It gave back a crazy matrix.
>
> setwd("/Users/deliashelton/Documents/Shelton
> back-up 11:21/labs/ABL meetings/DS7 Flow/DS7.5/Observers/AA 7.5/AA
> PND2/AA PND 2 22C")
>
> a<- list.files()
> xx<- c()
> t<-seq(0,3600, by = 60)
>
> for (i in a){
> name<- read.table(i,header=F)
> colnames(name)=c("Time", "Behavior")
> name<- data.frame(name$Behavior, name$Time)
> colnames(name)<-c("Behavior", "Time")
> name<-name[name$Time < 3600, ]
>
> if (tail(name$Behavior, 1) == 1) {name<-rbind(name, c(4, 3600))} else
> {name<-rbind(name, c(1, 3600))}
>
> if (((length(name$Behavior))) %% 2 != 0)
> {name <-name[-c(length(name$Behavior)), -c(length(name$Behavior))]}
>
>
> #xx <- rbind(xx, name)
>
> # total time partition by time which is 60
>
>
> q<-c()
> for (y in (1: (length(name$Behavior))))
> {
> if (y %% 2 == 0) {next} else
> {q<-c(q, (c(name$Time[y]:name$Time[y +1])))}
>
>
> }
>
> b<-table(cut(q,x))
> xx <- rbind(xx, sum(b))
>
> print(xx)
> }
>
> Crazy matrix:
>
> [,1]
> [1,] 4947
> [,1]
> [1,] 4947
> [2,] 7318
> [,1]
> [1,] 4947
> [2,] 7318
> [3,] 8598
> [,1]
> [1,] 4947
> [2,] 7318
> [3,] 8598
> [4,] 9617
> [,1]
> [1,] 4947
> [2,] 7318
> [3,] 8598
> [4,] 9617
> [5,] 11755
> [,1]
> [1,] 4947
> [2,] 7318
> [3,] 8598
> [4,] 9617
> [5,] 11755
> [6,] 13762
> [,1]
> [1,] 4947
> [2,] 7318
> [3,] 8598
> [4,] 9617
> [5,] 11755
> [6,] 13762
> [7,] 17363
> [,1]
> [1,] 4947
> [2,] 7318
> [3,] 8598
> [4,] 9617
> [5,] 11755
> [6,] 13762
> [7,] 17363
> [8,] 19857
> [,1]
> [1,] 4947
> [2,] 7318
> [3,] 8598
> [4,] 9617
> [5,] 11755
> [6,] 13762
> [7,] 17363
> [8,] 19857
> [9,] 23372
> [,1]
> [1,] 4947
> [2,] 7318
> [3,] 8598
> [4,] 9617
> [5,] 11755
> [6,] 13762
> [7,] 17363
> [8,] 19857
> [9,] 23372
> [10,] 25509
> [,1]
> [1,] 4947
> [2,] 7318
> [3,] 8598
> [4,] 9617
> [5,] 11755
> [6,] 13762
> [7,] 17363
> [8,] 19857
> [9,] 23372
> [10,] 25509
> [11,] 28071
> [,1]
> [1,] 4947
> [2,] 7318
> [3,] 8598
> [4,] 9617
> [5,] 11755
> [6,] 13762
> [7,] 17363
> [8,] 19857
> [9,] 23372
> [10,] 25509
> [11,] 28071
> [12,] 31672
> [,1]
> [1,] 4947
> [2,] 7318
> [3,] 8598
> [4,] 9617
> [5,] 11755
> [6,] 13762
> [7,] 17363
> [8,] 19857
> [9,] 23372
> [10,] 25509
> [11,] 28071
> [12,] 31672
> [13,] 35268
> [,1]
> [1,] 4947
> [2,] 7318
> [3,] 8598
> [4,] 9617
> [5,] 11755
> [6,] 13762
> [7,] 17363
> [8,] 19857
> [9,] 23372
> [10,] 25509
> [11,] 28071
> [12,] 31672
> [13,] 35268
> [14,] 38440
> [,1]
> [1,] 4947
> [2,] 7318
> [3,] 8598
> [4,] 9617
> [5,] 11755
> [6,] 13762
> [7,] 17363
> [8,] 19857
> [9,] 23372
> [10,] 25509
> [11,] 28071
> [12,] 31672
> [13,] 35268
> [14,] 38440
> [15,] 41796
> [,1]
> [1,] 4947
> [2,] 7318
> [3,] 8598
> [4,] 9617
> [5,] 11755
> [6,] 13762
> [7,] 17363
> [8,] 19857
> [9,] 23372
> [10,] 25509
> [11,] 28071
> [12,] 31672
> [13,] 35268
> [14,] 38440
> [15,] 41796
> [16,] 43142
>
>
> What I would like is for a recursive function/loop that
> follows the initial codes computation, but does it for all data files in the directory and binds the outputs into a single vector. If you have
> any tips on getting the code to work or can help identify the problem,
> your assistance would be appreciated.
> [[alternative HTML version deleted]]
>
>
> ______________________________________________
> 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.
>
>
More information about the R-help
mailing list