Is there a way I can make an lapply statement also show the index? More specifically, consider the following example:
mylist <- list(c(5,4),c(3,2), c(1,3))
myfunction<- function(values){
print("Adding values: ")
return(values[1] + values[2])
}
lapply(mylist, myfunction)
Is there a way I can somehow make it print "Adding Values: 1" "Adding Values: 2" etc.. one element of each in the list?
Thanks!
The function mapply
works like lapply
but allows you to supply multiple vectors or lists.
In your case you can create a second vector, the same length of the list, just counting up:
mapply(myfunction, mylist, seq_along(mylist))
Let's try it:
myfunction<- function(values, index){
cat("Adding values (", index, "): ", values[1], "...", values[2], " = ", sum(values), "\n" )
invisible(values[1] + values[2])
}
mylist <- list(c(5, 4), c(3, 2), c(1, 3))
mapply(myfunction, mylist, seq_along(mylist))
Result:
Adding values ( 1 ): 5 ... 4 = 9
Adding values ( 2 ): 3 ... 2 = 5
Adding values ( 3 ): 1 ... 3 = 4
Advanced user fun
Just for fun, a careful reading of the ?lapply
manual page reveals that the following also works:
myfunction<- function(values){
print(sprintf("Adding values: %i",substitute(values)[[3]]))
return(values[1] + values[2])
}
lapply(mylist, myfunction)
Which suggests a general function adaptor could be created to supply index to your original function (or any other), modified to expect a second index argument:
myfunction<- function(values,index){
print(sprintf("Adding values: %i",index))
return(values[1] + values[2])
}
Now the adaptor
lapply_index_adaptor=function(f)function(x,...)f(x,substitute(x)[[3]],...)
and now the lapply call, with the adaptor:
lapply(mylist, lapply_index_adaptor(myfunction))
It is good to use message
if you mean a message.
mylist <- list(c(5, 4), c(3, 2), c(1, 3))
If you want the index (on rereading this may be what you want)
myfunction_idx <- function(idx, x) {
.x <- x[[idx]]
message(sprintf("Adding values %s:", idx))
sum(.x)
}
lapply(seq_along(mylist), myfunction_idx, x = mylist)
## Adding values 1:
## Adding values 2:
## Adding values 3:
## [[1]]
## [1] 9
##
## [[2]]
## [1] 5
##
## [[3]]
## [1] 4
##
plyr solution
The plyr
package will construct a progress bar on the fly (lapply
will be quicker
library(plyr)
llply(mylist, sum, .progress = 'text')
Are you asking for 'commentary' on the particular values and process that is happening?
myfunction<- function(values){
cat("Adding values: ", values[1], "...", values[2], " = ", sum(values), "\n" )
invisible(values[1] + values[2])
}
lapply(mylist, myfunction)
Adding values: 5 ... 4 = 9
Adding values: 3 ... 2 = 5
Adding values: 1 ... 3 = 4
[[1]]
[1] 9
[[2]]
[1] 5
[[3]]
[1] 4
来源:https://stackoverflow.com/questions/12344982/r-lapply-statement-with-index