Benjamin Caldwell
2012-Sep-20 21:48 UTC
[R] question on assigning an argument in a function that is create by the function itself
Hi, I need some help with making a function a bit more elegant. How would you all suggest avoiding the problem I've made myself below - I've written a function that creates a temporary matrix by subseting a larger one I assign it. I then call vectors from that matrix, add each item in the vector to create a cumulative vector for each factor, and then patch them all back together. That's really an aside, because what I want to know is: how do I feed this or any function via its arguements the vectors I want it to deal with in advance, if those vectors are part of a matrix created in the function. My example is below. Thanks very much! Ben Caldwell #make some data a<-rep("a",9) b<-rep("b",9) c<-rep("c",9) level3<-c(a,b,c) abc d1<-9:1 set.seed(20) d2<-rnorm(9,1,.1) datas1<-d1*d2 e1<-rep(2.5,4) e2<-rep(10,5) datas2<-c(e1,e2) number<-rep(1:9,3) dummya<-data.frame(datas1,datas2,number) dummya dummy <- data.frame(level3,dummya) dummy #first function cumulative <- function(v,x) { b <- rep (2,length(v)) o<-order(x) v <-v[o] n<-length(v) b[1] <- v[1] for (i in 2:n) { b[i] <- v[i] + b[i-1] } b } #function I wish I could only write once with four arguments (two for v and x) not two cut.paste.1 <- function(datas, level3) { n <- length(unique(level)) sat <- NULL for (i in 1:n) { ref.frame<- datas[unique(level)[i] == level,] v <- ref.frame$datas1 # but I have to modify it below x <- ref.frame$number sat<-append(sat,cumulative (v,x)) } sat } cut.paste.1(dummy,level3) cut.paste.2 <- function(datas, level3) { n <- length(unique(level)) sat <- NULL for (i in 1:n) { ref.frame<- datas[unique(level)[i] == level,] v <- ref.frame$datas2 # here, but I wish I could make it an arguement for the function x <- ref.frame$number sat<-append(sat,cumulative (v,x)) } sat } cut.paste.2(dummy,level3) [[alternative HTML version deleted]]
Rui Barradas
2012-Sep-20 23:34 UTC
[R] question on assigning an argument in a function that is create by the function itself
Hello, Inline. Em 20-09-2012 22:48, Benjamin Caldwell escreveu:> Hi, > > I need some help with making a function a bit more elegant.Yes you do! Below, your first function, for instance, becomes a one liner. Trick: R is vectorized. Use functions that act on whole vectors, avoiding loops.> How would you > all suggest avoiding the problem I've made myself below - I've written a > function that creates a temporary matrixNo, not a matrix, a data.frame. They're very different, both conceptually and in implementation. A matrix is just a folded vector. To give a vector a 'dim' attribute changes its operative nature. It becomes the R implementation of the _linear_algebra_ concept of the same name. See ?matrix (and also ?array). A data.frame is a special type of ?list. It's R's implementation of the _statistical_ concept of variables and observations.> by subseting a larger one I assign > it. I then call vectors from that matrix, add each item in the vector to > create a cumulative vector for each factor, and then patch them all back > together. > > That's really an aside, because what I want to know is: how do I feed this > or any function via its arguements the vectors I want it to deal with in > advance, if those vectors are part of a matrix created in the function. My > example is below.Now some code. # first function (no longer needed) cumul2 <- function(v, x) cumsum( v[order(x)] ) # function to replace cut.paste.1 # (two for v and x) not two c.p.1 <- function(datas, level) { sp <- split(datas, level) sm <- sapply(sp, function(x) cumsum(x$datas1)) as.vector(sm) } c.p.1(dummy, level3) # function to replace both cut.paste.1 and cut.paste.2 cut_paste <- function(datas, column, level) { sp <- split(datas, level) sm <- sapply(sp, function(x) cumsum( x[[column]] )) as.vector(sm) } cut.paste.2(dummy, level3) cut_paste(dummy, "datas2", level3) cut.paste.1(dummy, level3) cut_paste(dummy, "datas1", level3) Hope this helps, Rui Barradas> > Thanks very much! > > Ben Caldwell > > #make some data > > a<-rep("a",9) > b<-rep("b",9) > c<-rep("c",9) > > level3<-c(a,b,c) > abc > d1<-9:1 > set.seed(20) > d2<-rnorm(9,1,.1) > datas1<-d1*d2 > > e1<-rep(2.5,4) > e2<-rep(10,5) > datas2<-c(e1,e2) > > > number<-rep(1:9,3) > dummya<-data.frame(datas1,datas2,number) > > dummya > dummy <- data.frame(level3,dummya) > dummy > > #first function > cumulative <- function(v,x) { > b <- rep (2,length(v)) > > o<-order(x) > v <-v[o] > > n<-length(v) > b[1] <- v[1] > for (i in 2:n) { > b[i] <- v[i] + b[i-1] > } > b > } > > #function I wish I could only write once with four arguments (two for v and > x) not two > cut.paste.1 <- function(datas, level3) { > > n <- length(unique(level)) > sat <- NULL > > for (i in 1:n) { > ref.frame<- datas[unique(level)[i] == level,] > v <- ref.frame$datas1 # but I have to modify it below > x <- ref.frame$number > sat<-append(sat,cumulative (v,x)) > } > sat > } > > cut.paste.1(dummy,level3) > > cut.paste.2 <- function(datas, level3) { > > n <- length(unique(level)) > sat <- NULL > > for (i in 1:n) { > ref.frame<- datas[unique(level)[i] == level,] > v <- ref.frame$datas2 # here, but I wish I could make it an arguement for > the function > x <- ref.frame$number > sat<-append(sat,cumulative (v,x)) > } > sat > } > > cut.paste.2(dummy,level3) > > [[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.