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-0003.ksh
[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
+}