[R] beginner programming question
Gabor Grothendieck
ggrothendieck at myway.com
Wed Dec 17 23:03:32 CET 2003
This is just a response to the part where you refer to an apply
loop really being a for loop. In a sense this true, but
it should nevertheless be recognized that the apply solution
has a number of advantages over for:
- it nicely separates the problem into a single line that is
independent of the details of the problem and localizes them
in f
- the rows are pasted together automatically avoiding messy
appending or creation and filling in of a structure
- it avoids the use of indices
Of course, some apply loops come pretty close to for loops. For
example, consider this variation:
t( matrix( unlist (sapply( 1:nrow(z), function(i) f(z[i,]) ) ), 2 ))
and compare it to the for loop:
out <- NULL
for ( i in 1:nrow(z) ) {
v <- f( z[i,] )
if ( ! is.null(v) ) out <- rbind( out, v )
}
but even this apply, which is clearly inferior to the one in my
original posting, retains the first two advantages listed.
---
Date: Thu, 18 Dec 2003 10:04:52 +1300 (NZDT)
From: Ray Brownrigg <ray at mcs.vuw.ac.nz>
To: <adi at roda.ro>, <ggrothendieck at myway.com>, <r-help at stat.math.ethz.ch>
Subject: RE: [R] beginner programming question
> From: "Gabor Grothendieck" <ggrothendieck at myway.com>
> Date: Wed, 17 Dec 2003 15:02:49 -0500 (EST)
>
> Define function f to take a vector as input representing
> a single input row. f should (1) transform this to a vector
> representing the required row of output or else (2) produce
> NULL if no row is to be output for that input row.
>
> Then use this code where z is your input matrix:
>
> t( matrix( unlist( apply( z, 1, f ) ), 2) )
>
But as has been pointed out recently, apply really is still just a for
loop.
> > From: Adrian Dusa <adi at roda.ro>
> > Date: Wed, 17 Dec 2003 21:28:05 +0200
> >
> > I have a (rather theoretical) programming problem for which I have found
> > a solution, but I feel it is a rather poor one. I wonder if there's some
> > other (more clever) solution, using (maybe?) vectorization or
> > subscripting.
Here is a subscripting solution, where (for consistency with above) z is
your data [from read.table(filename, header=T)]:
> z
rel1 rel2 rel3 age0 age1 age2 age3 sex0 sex1 sex2 sex3
1 1 3 NA 25 23 2 NA 1 2 1 NA
2 4 1 3 35 67 34 10 2 2 1 2
3 1 4 4 39 40 59 60 1 2 2 1
4 4 NA NA 45 70 NA NA 2 2 NA NA
> res <- matrix(NA, nrow=length(z[, 1]), ncol=2,
dimnames=list(rownames=rownames(z), colnames=c("ageh", "agew")))
> w <- w0 <- w1 <- w2 <- which(z[, c("rel1", "rel2", "rel3")] == 1, T)
# find spouse entries
> w0[, 2] <- z[, "sex0"][w[, 1]] # indices for respondent's age
> w1[, 2] <- 3 - w0[, 2] # indices for spouse's age
> w2[, 2] <- 4 + w[, 2] # indices of spouse's age
> res[w0] <- z[, "age0"][w[, 1]] # set respondent's age
> res[w1] <- z[w2] # set spouse's age
> res
colnames
rownames ageh agew
1 25 23
2 34 35
3 39 40
4 NA NA
>
Ray Brownrigg
More information about the R-help
mailing list