Thanks a lot to all people that reply to the list and personally: Mark
Leeds, Jo Jiao, Martin Studer, Christopher Green, Frank Harrell, Xao
Ping, Richard Heiberger, Sarah Goslee, Gerald Jean, Greg Johnson and
Rich from Mango.
Most solutions are variations of the same theme: change the function
definition, so it receives an array as an argument and then access the
elements of the array inside the function, either using names or the
position number of the array. Using Martin's code :
# Defining the data to use as test
my.a <- array(data = c(15, 10, 9, 11, 7.5, 10.5, 8.25, 9, 7.6, 10.7,
1.5,
1.0, 0.8, 1.3, 2.7, 1.0, 1.9, 1.4, 0.9, 1.55), dim = c(10, 2), dimnames
= list(NULL, c("Height", "Diameter")))
# A funny looking fake volume function
stem.volume <- function(datarow)
{
return(datarow["Height"]^2 / datarow["Diameter"])
}
# Using apply by rows (1), so it passes an array to the function
res <- apply(my.a, 1, stem.volume)
It is also possible to pass additional arguments to the functions (like
a constant) just appending them to the call, like:
res <- apply(my.a, 1, stem.volume, const = 3, z = 5)
Gerald Jean, pointed out something that I discovered when first
implementing the code sent by Martin: apply is slow, and in fact did not
perform very differently from a for() loop calling the function.
Other alternative codings:
- Frank Harrell suggests having a look at the mApply function in the
Hmisc package.
- Christopher Green offers this call:
apply(my.a, 1, function(x) stem.volume(x[1],x[2])), which would work
without the need for redefining the stem.volume function.
- Rich from Mango (yummy!) Solutions offers this alternative:
myMat <- matrix(rpois(20, 3), ncol=2) # Create some data
myFun <- function(x, y) x + y # Create a function
taking 2 numbers
apply(myMat, 1, function(x) do.call("myFun", as.list(x))) # Make the
call
- Richard Heiberger does something like:
# Tiny dataset
tmp <- cbind(h=10:13, d=5:6)
apply(tmp, 1, function(x) {x["h"] * x["d"]^2 * pi/4})
or
sapply(1:nrow(tmp), function(i, h, d) {h[i] * d[i]^2 * pi/4},
h=tmp[,"h"], d=tmp[,"d"])
Thanks again,
Luis
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Dr Luis A. Apiolaza
Principal Forest Biometrician
Forestry Tasmania
GPO Box 207
Hobart Tas 7001
Australia
email: Luis.Apiolaza@forestrytas.com.au
phone: +61-3-6233 8127
web: http://www.forestrytas.com.au
http://uncronopio.org
"All I want is a warm bed, a kind word,
and unlimited power" --Ashleigh Brilliant
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----------------------------------------------------
This transmission is intended solely for the person or
organisation to whom it is addressed.
It is confidential and may contain legally privileged
information. If you have received this transmission in
error,you may not use, copy or distribute it.
Please advise us by return e-mail or by phoning 61 3 62338203
and immediately delete the transmission in its entirety.
We will meet your reasonable expenses of notifying us.
Despite our use of anti-virus software, Forestry Tasmania
cannot guarantee that this transmission is virus-free.
-----------------------------------------------------
|