Hello, R-experts, In R-program,?I have a question about the apply-family. I want to use apply-family to replace a for-loop in my R-code,But, lapply returns a list of 3 (each component is the same), sapply returns a matrix, and mapply with error message. how to use apply-family function so that it returns a vector, as it does when using for-loop in my R-codes below? Hope to hear back soon! Thank you very much! #------------------------------------------------------------------------- # Below is my R-codes: #-----------? begin of ?R code -------------------------------------- # suppose list1 returned by fun1() # fun1() is a R-script with about 200 lines list1 <- list(u=3.8, v=53.42)# suppose list2 returned by fun2() # fun2() is a R-script with about 5000 lines list2 <- list(x=3.8, y=-9,3)# demo fun3(), the actual function is much more complicated fun3 <- function(xlist1, xlist2, xlist3) { ? ? x1 <- xlist1$u ? x2 <- xlist1$v ? ? x3 <- xlist2$x ? x4 <- xlist2$y ? ? x5 <- xlist3$x5 ? x6 <- xlist3$x6 ? x7 <- xlist3$x7 ? ? w <- x1^2 + sqrt(x2+x3) - 0.75*x4 + exp(x5) ? z <- sin(x2)/x7 + x6/(x3+x4) ? return(w+z) }dailyrecord <- data.frame(a = rnorm(50000), b = rnorm(50000), c = rnorm(50000), ????????????????????????? d = rnorm(50000), e = rnorm(50000), f = rnorm(50000), ????????????????????????? g = rnorm(50000)) result_forloop <- rep(0, 50000) # use for - loop ## how to avoid the for-loop ??for (k in 1 : 50000) { ? xlist <- list(x5 = dailyrecord$a[k], x6 = dailyrecord$e[k], x7 = dailyrecord$f[k]) ? result_forloop[k] <- fun3(list1, list2, xlist) }# use lapply? #--- return a list of 3 ------------ xlst <- list(x5=dailyrecord$a, x6 = dailyrecord$e, x7 = dailyrecord$f) result_lapply <- lapply(xlst, function(s) fun3(list1, list2, xlst)) # use sapply? #--- return a matrix? ------- result_sapply <- sapply(xlst, function(s) fun3(list1, list2, xlst)) # use mapply? #--- error? ------- result_mapply <- mapply(fun3, xlist1 = list1, xlist2 = list2, xlist3 = xlst) #-----------??end of?R code -------------------------------------- [[alternative HTML version deleted]]
You were very close. Try this. df <- data.frame(x5=dailyrecord$a, x6 = dailyrecord$e, x7 = dailyrecord$f) apply(df, 1, function(row) fun3(list1, list2, as.list(row))) Jean On Fri, Oct 9, 2015 at 3:15 PM, liqunhan--- via R-help <r-help at r-project.org> wrote:> > > Hello, R-experts, > In R-program, I have a question about the apply-family. > I want to use apply-family to replace a for-loop in my R-code,But, lapply > returns a list of 3 (each component is the same), sapply returns a matrix, > and mapply with error message. > how to use apply-family function so that it returns a vector, as it does > when using for-loop in my R-codes below? > Hope to hear back soon! > Thank you very much! > > > > #------------------------------------------------------------------------- > # Below is my R-codes: > #----------- begin of R code -------------------------------------- > # suppose list1 returned by fun1() > # fun1() is a R-script with about 200 lines > list1 <- list(u=3.8, v=53.42)# suppose list2 returned by fun2() > # fun2() is a R-script with about 5000 lines > list2 <- list(x=3.8, y=-9,3)# demo fun3(), the actual function is much > more complicated > fun3 <- function(xlist1, xlist2, xlist3) { > > x1 <- xlist1$u > x2 <- xlist1$v > > x3 <- xlist2$x > x4 <- xlist2$y > > x5 <- xlist3$x5 > x6 <- xlist3$x6 > x7 <- xlist3$x7 > > w <- x1^2 + sqrt(x2+x3) - 0.75*x4 + exp(x5) > z <- sin(x2)/x7 + x6/(x3+x4) > return(w+z) > }dailyrecord <- data.frame(a = rnorm(50000), b = rnorm(50000), c > rnorm(50000), > d = rnorm(50000), e = rnorm(50000), f > rnorm(50000), > g = rnorm(50000)) > result_forloop <- rep(0, 50000) > # use for - loop ## how to avoid the for-loop ??for (k in 1 : 50000) { > xlist <- list(x5 = dailyrecord$a[k], x6 = dailyrecord$e[k], x7 > dailyrecord$f[k]) > result_forloop[k] <- fun3(list1, list2, xlist) > }# use lapply #--- return a list of 3 ------------ > xlst <- list(x5=dailyrecord$a, x6 = dailyrecord$e, x7 = dailyrecord$f) > result_lapply <- lapply(xlst, function(s) fun3(list1, list2, xlst)) > > # use sapply #--- return a matrix ------- > result_sapply <- sapply(xlst, function(s) fun3(list1, list2, xlst)) > > # use mapply #--- error ------- > result_mapply <- mapply(fun3, xlist1 = list1, xlist2 = list2, xlist3 > xlst) > > #----------- end of R code -------------------------------------- > > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > 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.[[alternative HTML version deleted]]
On 10/10/15 10:56, Adams, Jean wrote:> You were very close. Try this. > > df <- data.frame(x5=dailyrecord$a, x6 = dailyrecord$e, x7 = dailyrecord$f) > apply(df, 1, function(row) fun3(list1, list2, as.list(row)))There could in general be problems with this approach. The apply() function works on *matrices* and if handed a data frame coerces it to a matrix. This is (usually!) OK if all columns of the data frame are of the same type, but the world could end if they are not. It is a good idea to *start* with a matrix if a matrix is what is required. And do not confuse data frames with matrices. They are very different animals. cheers, Rolf Turner -- Technical Editor ANZJS Department of Statistics University of Auckland Phone: +64-9-373-7599 ext. 88276
On 2015-10-09 20:15:16, liqunhan--- via R-help wrote:> for (k in 1 : 50000) { > ? xlist <- list(x5 = dailyrecord$a[k], x6 = dailyrecord$e[k], x7 = dailyrecord$f[k]) > ? result_forloop[k] <- fun3(list1, list2, xlist) > }result_forloop <- lapply( 1 : 50000, function( k) { tmpRow <- dailyrecord[ k, ] xlist <- with( df, list( x5= a, x6= e, x7= f)) fun3(list1, list2, xlist) })
correction: On 2015-10-10 16:08:39, Frank Schwidom wrote:> On 2015-10-09 20:15:16, liqunhan--- via R-help wrote: > > > for (k in 1 : 50000) { > > ? xlist <- list(x5 = dailyrecord$a[k], x6 = dailyrecord$e[k], x7 = dailyrecord$f[k]) > > ? result_forloop[k] <- fun3(list1, list2, xlist) > > } > > result_forloop <- lapply( 1 : 50000, function( k) { > > tmpRow <- dailyrecord[ k, ] > > xlist <- with( tmpRow, list( x5= a, x6= e, x7= f)) > > fun3(list1, list2, xlist) > > }) > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > 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. >