[R] Unexpected behaviour of apply()
Hello everyone, Considering the following code sample : indexes - function(vec) { vec - which(vec==TRUE) return(vec) } mat - matrix(FALSE, nrow=10, ncol=10) mat[1,3] - mat[3,1] - TRUE Issuing apply(mat, 1, indexes) returns a 10-cell list, as expected. Now if I do: mat[1,3] - mat[3,1] - FALSE apply(mat, 1, indexes) I would expect a 10-cell list with integer(0) in each cell - instead I get integer(0), which wrecks my further process. Is there a simple way to get the result I expect (and the only consistent one, IMHO) ? Thanks by advance for your help, Pierrick Bruneau http://www.bruneau44.com [[alternative HTML version deleted]] __ R-help@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.
Re: [R] Unexpected behaviour of apply()
Le vendredi 08 mars 2013 à 09:29 +0100, Pierrick Bruneau a écrit : Hello everyone, Considering the following code sample : indexes - function(vec) { vec - which(vec==TRUE) return(vec) } This is essentially which(), what did you write such a convoluted function to get the same result? mat - matrix(FALSE, nrow=10, ncol=10) mat[1,3] - mat[3,1] - TRUE Issuing apply(mat, 1, indexes) returns a 10-cell list, as expected. Now if I do: mat[1,3] - mat[3,1] - FALSE apply(mat, 1, indexes) I would expect a 10-cell list with integer(0) in each cell - instead I get integer(0), which wrecks my further process. From ?apply: If each call to ‘FUN’ returns a vector of length ‘n’, then ‘apply’ returns an array of dimension ‘c(n, dim(X)[MARGIN])’ if ‘n 1’. If ‘n’ equals ‘1’, ‘apply’ returns a vector if ‘MARGIN’ has length 1 and an array of dimension ‘dim(X)[MARGIN]’ otherwise. If ‘n’ is ‘0’, the result has length 0 but not necessarily the ‘correct’ dimension. Note especially the last sentence. Is there a simple way to get the result I expect (and the only consistent one, IMHO) ? One of the interests of apply() is that it combines the return values from all function calls into a convenient form, but this can indeed be a problem if you cannot know in advance what this form will be. If you need a list in all cases, then just call lapply(): lapply(seq(nrow(mat)), function(i) which(mat[i,])) Regards Thanks by advance for your help, Pierrick Bruneau http://www.bruneau44.com [[alternative HTML version deleted]] __ R-help@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. __ R-help@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.
Re: [R] Unexpected behaviour of apply()
This is nice fodder for 'The R Inferno' -- thanks. As Milan said, 'which' will suffice as the function. Here is a specialized function that only returns a list and is only implemented to work with matrices. It should solve your current dilemma. applyL - function (X, MARGIN, FUN, ...) { stopifnot(length(dim(X)) == 2, length(MARGIN) == 1) FUN - match.fun(FUN) ans - vector(list, dim(X)[MARGIN]) if(MARGIN == 1) { for(i in seq_along(ans)) { ans[[i]] - FUN(X[i,], ...) } } else { for(i in seq_along(ans)) { ans[[i]] - FUN(X[,i], ...) } } names(ans) - dimnames(X)[[MARGIN]] ans } Pat On 08/03/2013 08:29, Pierrick Bruneau wrote: Hello everyone, Considering the following code sample : indexes - function(vec) { vec - which(vec==TRUE) return(vec) } mat - matrix(FALSE, nrow=10, ncol=10) mat[1,3] - mat[3,1] - TRUE Issuing apply(mat, 1, indexes) returns a 10-cell list, as expected. Now if I do: mat[1,3] - mat[3,1] - FALSE apply(mat, 1, indexes) I would expect a 10-cell list with integer(0) in each cell - instead I get integer(0), which wrecks my further process. Is there a simple way to get the result I expect (and the only consistent one, IMHO) ? Thanks by advance for your help, Pierrick Bruneau http://www.bruneau44.com [[alternative HTML version deleted]] __ R-help@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. -- Patrick Burns pbu...@pburns.seanet.com twitter: @burnsstat @portfolioprobe http://www.portfolioprobe.com/blog http://www.burns-stat.com (home of: 'Impatient R' 'The R Inferno' 'Tao Te Programming') __ R-help@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.
Re: [R] Unexpected behaviour of apply()
Thanks for your replies ! The lapply hack does the job in my context, so I'll stick to it (and actually in any case where I expect variable length results). About your quote from ?apply : I read it some time ago actually - but with my recent use in variable length returning FUN, I got fooled... On Fri, Mar 8, 2013 at 10:43 AM, Patrick Burns pbu...@pburns.seanet.comwrote: This is nice fodder for 'The R Inferno' -- thanks. As Milan said, 'which' will suffice as the function. Here is a specialized function that only returns a list and is only implemented to work with matrices. It should solve your current dilemma. applyL - function (X, MARGIN, FUN, ...) { stopifnot(length(dim(X)) == 2, length(MARGIN) == 1) FUN - match.fun(FUN) ans - vector(list, dim(X)[MARGIN]) if(MARGIN == 1) { for(i in seq_along(ans)) { ans[[i]] - FUN(X[i,], ...) } } else { for(i in seq_along(ans)) { ans[[i]] - FUN(X[,i], ...) } } names(ans) - dimnames(X)[[MARGIN]] ans } Pat On 08/03/2013 08:29, Pierrick Bruneau wrote: Hello everyone, Considering the following code sample : indexes - function(vec) { vec - which(vec==TRUE) return(vec) } mat - matrix(FALSE, nrow=10, ncol=10) mat[1,3] - mat[3,1] - TRUE Issuing apply(mat, 1, indexes) returns a 10-cell list, as expected. Now if I do: mat[1,3] - mat[3,1] - FALSE apply(mat, 1, indexes) I would expect a 10-cell list with integer(0) in each cell - instead I get integer(0), which wrecks my further process. Is there a simple way to get the result I expect (and the only consistent one, IMHO) ? Thanks by advance for your help, Pierrick Bruneau http://www.bruneau44.com [[alternative HTML version deleted]] __** R-help@r-project.org mailing list https://stat.ethz.ch/mailman/**listinfo/r-helphttps://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/** posting-guide.html http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. -- Patrick Burns pbu...@pburns.seanet.com twitter: @burnsstat @portfolioprobe http://www.portfolioprobe.com/**blog http://www.portfolioprobe.com/blog http://www.burns-stat.com (home of: 'Impatient R' 'The R Inferno' 'Tao Te Programming') [[alternative HTML version deleted]] __ R-help@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.