[R] question on assigning an argument in a function that is create by the function itself

Rui Barradas ruipbarradas at sapo.pt
Fri Sep 21 01:34:56 CEST 2012


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 matrix

No, 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.




More information about the R-help mailing list