Hello! I have noticed that mapply() drops names in R 2.3.1 as well as in r-devel. Here is a simple example: l <- list(a=1, b=2) k <- list(1) mapply(FUN="+", l, k) [1] 2 3 mapply(FUN="+", l, k, SIMPLIFY=FALSE) [[1]] [1] 2 [[2]] [1] 3 Help page does not indicate that this should happen. Argument USE.NAMES does not have any effect here as it used only in a bit special situation: "If the first ... argument is character and the result does not already have names, use it as the names." But result is always without names as shown above. Did I miss any peculiarities? This is not consistent with lapply, which keeps names i.e. lapply(l, "+", 1) $a [1] 2 $b [1] 3 I have attached and copied (at the end) patch proposal against SVN that adds names back to the result if x had it (only R as my C is ...). This way it would also be consistent with lapply. make check-all seems to be happy with changes. Now we get: mapply(FUN="+", l, k) a b 2 3 mapply(FUN="+", l, k, SIMPLIFY=FALSE) $a [1] 2 $b [1] 3 And if we had "character" (with some variations) for first ... then: l <- list(a="1", b="2") mapply(FUN="paste", l, k) a b "1 1" "2 1" l <- list("1", "2") mapply(FUN="paste", l, k) [1] "1 1" "2 1" l <- c("1", "2") mapply(FUN="paste", l, k) 1 2 "1 1" "2 1" Index: src/library/base/R/mapply.R ==================================================================--- src/library/base/R/mapply.R (revision 39024) +++ src/library/base/R/mapply.R (working copy) @@ -3,8 +3,16 @@ FUN <- match.fun(FUN) dots <- list(...) + if(!is.null(names(dots[[1]]))) { + isNamed <- TRUE + namesX <- names(dots[[1]]) + } else { + isNamed <- FALSE + } + answer<-.Call("do_mapply", FUN, dots, MoreArgs, environment(), PACKAGE="base") + if(isNamed) names(answer) <- namesX if (USE.NAMES && length(dots) && is.character(dots[[1]]) && is.null(names(answer))) names(answer) <- dots[[1]] @@ -47,4 +55,4 @@ } formals(FUNV) <- formals(FUN) FUNV -} \ No newline at end of file +} -- Lep pozdrav / With regards, Gregor Gorjanc ---------------------------------------------------------------------- University of Ljubljana PhD student Biotechnical Faculty Zootechnical Department URI: http://www.bfro.uni-lj.si/MR/ggorjan Groblje 3 mail: gregor.gorjanc <at> bfro.uni-lj.si SI-1230 Domzale tel: +386 (0)1 72 17 861 Slovenia, Europe fax: +386 (0)1 72 17 888 ---------------------------------------------------------------------- "One must learn by doing the thing; for though you think you know it, you have no certainty until you try." Sophocles ~ 450 B.C. ---------------------------------------------------------------------- -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: mapply.R.namesPatch Url: https://stat.ethz.ch/pipermail/r-devel/attachments/20060831/0a234e2c/attachment-0004.ksh
Gregor: Works for me on 2.3.0:> mapply(function(x,y,z) paste(y,z), letters,as.list(LETTERS),as.list(1:26))[ 1:5 ]a b c d e "A 1" "B 2" "C 3" "D 4" "E 5"> mapply(function(x,y,z) paste(x,y,z), letters,as.list(LETTERS),as.list(1:26))[ 1:5 ]a b c d e "a A 1" "b B 2" "c C 3" "d D 4" "e E 5">but this does not yield names:> mapply(function(x,y,z) paste(x,y,z), as.list(letters),as.list(LETTERS),as.list(1:26))[ 1:5 ][1] "a A 1" "b B 2" "c C 3" "d D 4" "e E 5" Perhaps the help page would be clearer if it said: USE.NAMES: If the first ... argument is a character ***vector*** and the result doesn't already have names, use it as the names Chuck On Thu, 31 Aug 2006, Gregor Gorjanc wrote:> Hello! > > I have noticed that mapply() drops names in R 2.3.1 as well as in > r-devel. Here is a simple example: > > l <- list(a=1, b=2) > k <- list(1) > mapply(FUN="+", l, k) > [1] 2 3 > mapply(FUN="+", l, k, SIMPLIFY=FALSE) > [[1]] > [1] 2 > > [[2]] > [1] 3 > > Help page does not indicate that this should happen. Argument USE.NAMES > does not have any effect here as it used only in a bit special > situation: "If the first ... argument is character and the result does > not already have names, use it as the names." But result is always > without names as shown above. Did I miss any peculiarities? > > This is not consistent with lapply, which keeps names i.e. > > lapply(l, "+", 1) > $a > [1] 2 > > $b > [1] 3 > > I have attached and copied (at the end) patch proposal against SVN that > adds names back to the result if x had it (only R as my C is ...). This > way it would also be consistent with lapply. make check-all seems to be > happy with changes. Now we get: > > mapply(FUN="+", l, k) > a b > 2 3 > > mapply(FUN="+", l, k, SIMPLIFY=FALSE) > $a > [1] 2 > > $b > [1] 3 > > And if we had "character" (with some variations) for first ... then: > > l <- list(a="1", b="2") > mapply(FUN="paste", l, k) > a b > "1 1" "2 1" > > l <- list("1", "2") > mapply(FUN="paste", l, k) > [1] "1 1" "2 1" > > l <- c("1", "2") > mapply(FUN="paste", l, k) > 1 2 > "1 1" "2 1" > > Index: src/library/base/R/mapply.R > ==================================================================> --- src/library/base/R/mapply.R (revision 39024) > +++ src/library/base/R/mapply.R (working copy) > @@ -3,8 +3,16 @@ > FUN <- match.fun(FUN) > dots <- list(...) > > + if(!is.null(names(dots[[1]]))) { > + isNamed <- TRUE > + namesX <- names(dots[[1]]) > + } else { > + isNamed <- FALSE > + } > + > answer<-.Call("do_mapply", FUN, dots, MoreArgs, environment(), > PACKAGE="base") > + if(isNamed) names(answer) <- namesX > > if (USE.NAMES && length(dots) && is.character(dots[[1]]) && > is.null(names(answer))) names(answer) <- dots[[1]] > @@ -47,4 +55,4 @@ > } > formals(FUNV) <- formals(FUN) > FUNV > -} > \ No newline at end of file > +} > > -- > Lep pozdrav / With regards, > Gregor Gorjanc > > ---------------------------------------------------------------------- > University of Ljubljana PhD student > Biotechnical Faculty > Zootechnical Department URI: http://www.bfro.uni-lj.si/MR/ggorjan > Groblje 3 mail: gregor.gorjanc <at> bfro.uni-lj.si > > SI-1230 Domzale tel: +386 (0)1 72 17 861 > Slovenia, Europe fax: +386 (0)1 72 17 888 > > ---------------------------------------------------------------------- > "One must learn by doing the thing; for though you think you know it, > you have no certainty until you try." Sophocles ~ 450 B.C. > ---------------------------------------------------------------------- >Charles C. Berry (858) 534-2098 Dept of Family/Preventive Medicine E mailto:cberry at tajo.ucsd.edu UC San Diego http://biostat.ucsd.edu/~cberry/ La Jolla, San Diego 92093-0717
Hello, Charles Berry sent me (off-list) his proposal, which I find better (after slight modification) than mine. I would say that proposed changes make mapply even more consistent with (some) *apply* funcs in terms of names. Patches to mapply.R and mapply.Rd are attached. I have runned make check-all and it seems that there are no problems with this change. I hope R core will find this worth to apply. New behaviour without first ... as character: l <- list(a=1, b=2) k <- list(1) mapply(FUN="+", l, k) a b 2 3 mapply(FUN="+", l, k, USE.NAMES=FALSE) [1] 2 3 mapply(FUN="+", l, k, SIMPLIFY=FALSE) $a [1] 2 $b [1] 3 mapply(FUN="+", l, k, SIMPLIFY=FALSE, USE.NAMES=FALSE) [[1]] [1] 2 [[2]] [1] 3 New behaviour with first ... as character _with_ names: l <- c("1", "2") names(l) <- c("a", "b") mapply(FUN="paste", l, k) a b "1 1" "2 1" mapply(FUN="paste", l, k, USE.NAMES=FALSE) [1] "1 1" "2 1" mapply(FUN="paste", l, k, SIMPLIFY=FALSE) $a [1] "1 1" $b [1] "2 1" mapply(FUN="paste", l, k, SIMPLIFY=FALSE, USE.NAMES=FALSE) [[1]] [1] "1 1" [[2]] [1] "2 1" New behaviour with first ... as character _without_ names: l <- c("1", "2") mapply(FUN="paste", l, k) 1 2 "1 1" "2 1" mapply(FUN="paste", l, k, USE.NAMES=FALSE) [1] "1 1" "2 1" mapply(FUN="paste", l, k, SIMPLIFY=FALSE) $`1` [1] "1 1" $`2` [1] "2 1" mapply(FUN="paste", l, k, SIMPLIFY=FALSE, USE.NAMES=FALSE) [[1]] [1] "1 1" [[2]] [1] "2 1" Regards, Gregor Gregor Gorjanc wrote:> Hello! > > I have noticed that mapply() drops names in R 2.3.1 as well as in > r-devel. Here is a simple example: > > l <- list(a=1, b=2) > k <- list(1) > mapply(FUN="+", l, k) > [1] 2 3 > mapply(FUN="+", l, k, SIMPLIFY=FALSE) > [[1]] > [1] 2 > > [[2]] > [1] 3 > > Help page does not indicate that this should happen. Argument USE.NAMES > does not have any effect here as it used only in a bit special > situation: "If the first ... argument is character and the result does > not already have names, use it as the names." But result is always > without names as shown above. Did I miss any peculiarities? > > This is not consistent with lapply, which keeps names i.e. > > lapply(l, "+", 1) > $a > [1] 2 > > $b > [1] 3 > > I have attached and copied (at the end) patch proposal against SVN that > adds names back to the result if x had it (only R as my C is ...). This > way it would also be consistent with lapply. make check-all seems to be > happy with changes. Now we get: > > mapply(FUN="+", l, k) > a b > 2 3 > > mapply(FUN="+", l, k, SIMPLIFY=FALSE) > $a > [1] 2 > > $b > [1] 3 > > And if we had "character" (with some variations) for first ... then: > > l <- list(a="1", b="2") > mapply(FUN="paste", l, k) > a b > "1 1" "2 1" > > l <- list("1", "2") > mapply(FUN="paste", l, k) > [1] "1 1" "2 1" > > l <- c("1", "2") > mapply(FUN="paste", l, k) > 1 2 > "1 1" "2 1" > > Index: src/library/base/R/mapply.R > ==================================================================> --- src/library/base/R/mapply.R (revision 39024) > +++ src/library/base/R/mapply.R (working copy) > @@ -3,8 +3,16 @@ > FUN <- match.fun(FUN) > dots <- list(...) > > + if(!is.null(names(dots[[1]]))) { > + isNamed <- TRUE > + namesX <- names(dots[[1]]) > + } else { > + isNamed <- FALSE > + } > + > answer<-.Call("do_mapply", FUN, dots, MoreArgs, environment(), > PACKAGE="base") > + if(isNamed) names(answer) <- namesX > > if (USE.NAMES && length(dots) && is.character(dots[[1]]) && > is.null(names(answer))) names(answer) <- dots[[1]] > @@ -47,4 +55,4 @@ > } > formals(FUNV) <- formals(FUN) > FUNV > -} > \ No newline at end of file > +} > > > > ------------------------------------------------------------------------ > > Index: src/library/base/R/mapply.R > ==================================================================> --- src/library/base/R/mapply.R (revision 39024) > +++ src/library/base/R/mapply.R (working copy) > @@ -3,8 +3,16 @@ > FUN <- match.fun(FUN) > dots <- list(...) > > + if(!is.null(names(dots[[1]]))) { > + isNamed <- TRUE > + namesX <- names(dots[[1]]) > + } else { > + isNamed <- FALSE > + } > + > answer<-.Call("do_mapply", FUN, dots, MoreArgs, environment(), > PACKAGE="base") > + if(isNamed) names(answer) <- namesX > > if (USE.NAMES && length(dots) && is.character(dots[[1]]) && > is.null(names(answer))) names(answer) <- dots[[1]] > @@ -47,4 +55,4 @@ > } > formals(FUNV) <- formals(FUN) > FUNV > -} > \ No newline at end of file > +}-------------- next part -------------- A non-text attachment was scrubbed... Name: mapply.R.patch.gz Type: application/x-gzip Size: 446 bytes Desc: not available Url : https://stat.ethz.ch/pipermail/r-devel/attachments/20060831/80849894/attachment-0010.gz -------------- next part -------------- A non-text attachment was scrubbed... Name: mapply.Rd.patch.gz Type: application/x-gzip Size: 438 bytes Desc: not available Url : https://stat.ethz.ch/pipermail/r-devel/attachments/20060831/80849894/attachment-0011.gz