John Kane
2006-Aug-24 21:30 UTC
[R] Using a 'for' loop : there should be a better way in R
I need to apply a yearly inflation factor to some wages and supply some simple sums by work category. I have gone at it with a brute force "for" loop approach which seems okay as it is a small dataset. It looks a bit inelegant and given all the warnings in the Intro to R, etc, about using loops I wondered if anyone could suggest something a bit simpler or more efficent? Example: cat1 <- c( 1,1,6,1,1,5) cat2 <- c( 1,2,3,4,5,6) cat3 <- c( 5,4,6,7,8,8) cat4 <- c( 1,2,1,2,1,2) years <- c( 'year1', 'year2', 'year3', 'year3', 'year1', 'year1') id <- c('a','a','b','c','c','a') df1 <- data.frame(id,years,cat1,cat2, cat3, cat4) nn <- levels(df1$id) # levels for outer loop hh <- levels(df1$years) # levels for inter loop mp <- c(1, 5, 10) # inflation factor tt <- data.frame(matrix(NA, length(nn), 2)) names(tt) <- c("s1","s2") rownames(tt) <- nn for (i in 1:length(nn)){ scat <- data.frame(matrix(NA, length(hh),2)) dd1 <- subset(df1, id==nn[i]) for (j in 1:length(hh)){ dd2 <- subset(dd1, dd1$years==hh[j]) s1 <- sum(dd2$cat1,dd2$cat2, na.rm=T) s2 <- sum(dd2$cat3,dd2$cat4,na.rm=T) scat[j,] <- c(s1,s2) *mp[j] # multiply by the inflation factor } crush <- apply(scat, 2, sum) tt[i,] <- crush } tt
Gabor Grothendieck
2006-Aug-24 23:04 UTC
[R] Using a 'for' loop : there should be a better way in R
Use cbind to create a two column matrix, mat, and multiply that by the appropriate inflation factors. Then use rowsum to sum the rows according to the id grouping factor. inf.fac <- list(year1 = 1, year2 = 5, year3 = 10) mat <- cbind(s1 = df1$cat1 + df1$cat2, s2 = df1$cat3 + df1$cat4) rowsum(mat * unlist(inf.fac[df1$year]), df1$id) On 8/24/06, John Kane <jrkrideau at yahoo.ca> wrote:> I need to apply a yearly inflation factor to some > wages and supply some simple sums by work category. I > have gone at it with a brute force "for" loop approach > which seems okay as it is a small dataset. It looks > a bit inelegant and given all the warnings in the > Intro to R, etc, about using loops I wondered if > anyone could suggest something a bit simpler or more > efficent? > > Example: > > cat1 <- c( 1,1,6,1,1,5) > cat2 <- c( 1,2,3,4,5,6) > cat3 <- c( 5,4,6,7,8,8) > cat4 <- c( 1,2,1,2,1,2) > years <- c( 'year1', 'year2', 'year3', 'year3', > 'year1', 'year1') > id <- c('a','a','b','c','c','a') > df1 <- data.frame(id,years,cat1,cat2, cat3, cat4) > > nn <- levels(df1$id) # levels for outer loop > hh <- levels(df1$years) # levels for inter loop > > > mp <- c(1, 5, 10) # inflation factor > > tt <- data.frame(matrix(NA, length(nn), 2)) > names(tt) <- c("s1","s2") > rownames(tt) <- nn > > for (i in 1:length(nn)){ > scat <- data.frame(matrix(NA, length(hh),2)) > dd1 <- subset(df1, id==nn[i]) > for (j in 1:length(hh)){ > dd2 <- subset(dd1, dd1$years==hh[j]) > s1 <- sum(dd2$cat1,dd2$cat2, na.rm=T) > s2 <- sum(dd2$cat3,dd2$cat4,na.rm=T) > scat[j,] <- c(s1,s2) *mp[j] # multiply by the > inflation factor > } > crush <- apply(scat, 2, sum) > tt[i,] <- crush > } > tt > > ______________________________________________ > R-help at stat.math.ethz.ch 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. >