David L Carlson
2017-Jun-01 18:34 UTC
[R] Reversing one dimension of an array, in a generalized case
Here is an alternative approach using apply(). Note that with apply() you are reversing rows or columns not indices of rows or columns so apply(junk, 2, rev) reverses the values in each column not the column indices. We actually need to use rev() on everything but the index we are interested in reversing: f2 <- function(a, wh) { dims <- seq_len(length(dim(a))) dims <- setdiff(dims, wh) apply(apply(a, dims, rev), dims, t) } # Your example j1 <- junk[ , rev(1:10), ] j2 <- f2(junk, 2) all.equal(j1, j2) # [1] TRUE # Bert's example z1 <- f(z, 2) z2 <- f2(z, 2) all.equal(z1, z2) # [1] TRUE ------------------------------------- David L Carlson Department of Anthropology Texas A&M University College Station, TX 77840-4352 -----Original Message----- From: R-help [mailto:r-help-bounces at r-project.org] On Behalf Of Bert Gunter Sent: Thursday, June 1, 2017 12:46 PM To: Roy Mendelssohn - NOAA Federal <roy.mendelssohn at noaa.gov> Cc: R-help <r-help at r-project.org> Subject: Re: [R] Reversing one dimension of an array, in a generalized case How about this: f <- function(a,wh){ ## a is the array; wh is the index to be reversed l<- lapply(dim(a),seq_len) l[[wh]]<- rev(l[[wh]]) do.call(`[`,c(list(a),l)) } ## test z <- array(1:120,dim=2:5) ## I omit the printouts f(z,2) f(z,3) Cheers, Bert Bert Gunter "The trouble with having an open mind is that people keep coming along and sticking things into it." -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) On Thu, Jun 1, 2017 at 9:51 AM, Roy Mendelssohn - NOAA Federal <roy.mendelssohn at noaa.gov> wrote:> Hi All: > > I have been looking for an elegant way to do the following, but haven't found it, I have never had a good understanding of any of the "apply" functions. > > A simplified idea is I have an array, say: > > junk(5, 10, 3) > > where (5, 10, 3) give the dimension sizes, and I want to reverse the second dimension, so I could do: > > junk1 <- junk[, rev(seq_len(10), ] > > but what I am after is a general function that will do that where the array could be two, three or four dimensions, and I pass to the function which dimension I want to reverse, that is the function can not assume the number of dimensions of the array nor which dimension to reverse. > > For example, if i try: > > junk1 <- apply(junk, 2, rev) > > junk1 comes out as two-dimensional, not three-dimensional. > > It is probably something obvious but I am not getting it. > > Thanks for any help. > > -Roy > > > ********************** > "The contents of this message do not reflect any position of the U.S. Government or NOAA." > ********************** > Roy Mendelssohn > Supervisory Operations Research Analyst > NOAA/NMFS > Environmental Research Division > Southwest Fisheries Science Center > ***Note new street address*** > 110 McAllister Way > Santa Cruz, CA 95060 > Phone: (831)-420-3666 > Fax: (831) 420-3980 > e-mail: Roy.Mendelssohn at noaa.gov www: http://www.pfeg.noaa.gov/ > > "Old age and treachery will overcome youth and skill." > "From those who have been given much, much will be expected" > "the arc of the moral universe is long, but it bends toward justice" -MLK Jr. > > ______________________________________________ > 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.______________________________________________ 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.
Bert Gunter
2017-Jun-01 19:00 UTC
[R] Reversing one dimension of an array, in a generalized case
??> z <- array(1:24,dim=2:4) > all.equal(f(z,3),f2(z,3))[1] "Attributes: < Component ?dim?: Mean relative difference: 0.4444444 >" [2] "Mean relative difference: 0.6109091" In fact,> dim(f(z,3))[1] 2 3 4> dim(f2(z,3))[1] 3 4 2 Have I made some sort of stupid error here? Or have I misunderstood what was wanted? Cheers, Bert Bert Gunter "The trouble with having an open mind is that people keep coming along and sticking things into it." -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) On Thu, Jun 1, 2017 at 11:34 AM, David L Carlson <dcarlson at tamu.edu> wrote:> Here is an alternative approach using apply(). Note that with apply() you are reversing rows or columns not indices of rows or columns so apply(junk, 2, rev) reverses the values in each column not the column indices. We actually need to use rev() on everything but the index we are interested in reversing: > > f2 <- function(a, wh) { > dims <- seq_len(length(dim(a))) > dims <- setdiff(dims, wh) > apply(apply(a, dims, rev), dims, t) > } > > # Your example > j1 <- junk[ , rev(1:10), ] > j2 <- f2(junk, 2) > all.equal(j1, j2) > # [1] TRUE > > # Bert's example > z1 <- f(z, 2) > z2 <- f2(z, 2) > all.equal(z1, z2) > # [1] TRUE > > ------------------------------------- > David L Carlson > Department of Anthropology > Texas A&M University > College Station, TX 77840-4352 > > > > > > > -----Original Message----- > From: R-help [mailto:r-help-bounces at r-project.org] On Behalf Of Bert Gunter > Sent: Thursday, June 1, 2017 12:46 PM > To: Roy Mendelssohn - NOAA Federal <roy.mendelssohn at noaa.gov> > Cc: R-help <r-help at r-project.org> > Subject: Re: [R] Reversing one dimension of an array, in a generalized case > > How about this: > > f <- function(a,wh){ ## a is the array; wh is the index to be reversed > l<- lapply(dim(a),seq_len) > l[[wh]]<- rev(l[[wh]]) > do.call(`[`,c(list(a),l)) > } > > ## test > z <- array(1:120,dim=2:5) > > ## I omit the printouts > > f(z,2) > > f(z,3) > > > Cheers, > Bert > > Bert Gunter > > "The trouble with having an open mind is that people keep coming along > and sticking things into it." > -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) > > > On Thu, Jun 1, 2017 at 9:51 AM, Roy Mendelssohn - NOAA Federal > <roy.mendelssohn at noaa.gov> wrote: >> Hi All: >> >> I have been looking for an elegant way to do the following, but haven't found it, I have never had a good understanding of any of the "apply" functions. >> >> A simplified idea is I have an array, say: >> >> junk(5, 10, 3) >> >> where (5, 10, 3) give the dimension sizes, and I want to reverse the second dimension, so I could do: >> >> junk1 <- junk[, rev(seq_len(10), ] >> >> but what I am after is a general function that will do that where the array could be two, three or four dimensions, and I pass to the function which dimension I want to reverse, that is the function can not assume the number of dimensions of the array nor which dimension to reverse. >> >> For example, if i try: >> >> junk1 <- apply(junk, 2, rev) >> >> junk1 comes out as two-dimensional, not three-dimensional. >> >> It is probably something obvious but I am not getting it. >> >> Thanks for any help. >> >> -Roy >> >> >> ********************** >> "The contents of this message do not reflect any position of the U.S. Government or NOAA." >> ********************** >> Roy Mendelssohn >> Supervisory Operations Research Analyst >> NOAA/NMFS >> Environmental Research Division >> Southwest Fisheries Science Center >> ***Note new street address*** >> 110 McAllister Way >> Santa Cruz, CA 95060 >> Phone: (831)-420-3666 >> Fax: (831) 420-3980 >> e-mail: Roy.Mendelssohn at noaa.gov www: http://www.pfeg.noaa.gov/ >> >> "Old age and treachery will overcome youth and skill." >> "From those who have been given much, much will be expected" >> "the arc of the moral universe is long, but it bends toward justice" -MLK Jr. >> >> ______________________________________________ >> 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. > > ______________________________________________ > 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.
David L Carlson
2017-Jun-01 19:22 UTC
[R] Reversing one dimension of an array, in a generalized case
My error. Clearly I did not do enough testing. z <- array(1:24,dim=2:4)> all.equal(f(z,1),f2(z,1))[1] TRUE> all.equal(f(z,2),f2(z,2))[1] TRUE> all.equal(f(z,3),f2(z,3))[1] "Attributes: < Component ?dim?: Mean relative difference: 0.4444444 >" [2] "Mean relative difference: 0.6109091" # Your earlier example> z <- array(1:120, dim=2:5) > all.equal(f(z,1),f2(z,1))[1] TRUE> all.equal(f(z,2),f2(z,2))[1] TRUE> all.equal(f(z,3),f2(z,3))[1] "Attributes: < Component ?dim?: Mean relative difference: 0.4444444 >" [2] "Mean relative difference: 0.1262209"> all.equal(f(z,4),f2(z,4))[1] "Attributes: < Component ?dim?: Mean relative difference: 0.5714286 >" [2] "Mean relative difference: 0.5855162" David C -----Original Message----- From: Bert Gunter [mailto:bgunter.4567 at gmail.com] Sent: Thursday, June 1, 2017 2:00 PM To: David L Carlson <dcarlson at tamu.edu> Cc: Roy Mendelssohn - NOAA Federal <roy.mendelssohn at noaa.gov>; R-help <r-help at r-project.org> Subject: Re: [R] Reversing one dimension of an array, in a generalized case ??> z <- array(1:24,dim=2:4) > all.equal(f(z,3),f2(z,3))[1] "Attributes: < Component ?dim?: Mean relative difference: 0.4444444 >" [2] "Mean relative difference: 0.6109091" In fact,> dim(f(z,3))[1] 2 3 4> dim(f2(z,3))[1] 3 4 2 Have I made some sort of stupid error here? Or have I misunderstood what was wanted? Cheers, Bert Bert Gunter "The trouble with having an open mind is that people keep coming along and sticking things into it." -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) On Thu, Jun 1, 2017 at 11:34 AM, David L Carlson <dcarlson at tamu.edu> wrote:> Here is an alternative approach using apply(). Note that with apply() you are reversing rows or columns not indices of rows or columns so apply(junk, 2, rev) reverses the values in each column not the column indices. We actually need to use rev() on everything but the index we are interested in reversing: > > f2 <- function(a, wh) { > dims <- seq_len(length(dim(a))) > dims <- setdiff(dims, wh) > apply(apply(a, dims, rev), dims, t) > } > > # Your example > j1 <- junk[ , rev(1:10), ] > j2 <- f2(junk, 2) > all.equal(j1, j2) > # [1] TRUE > > # Bert's example > z1 <- f(z, 2) > z2 <- f2(z, 2) > all.equal(z1, z2) > # [1] TRUE > > ------------------------------------- > David L Carlson > Department of Anthropology > Texas A&M University > College Station, TX 77840-4352 > > > > > > > -----Original Message----- > From: R-help [mailto:r-help-bounces at r-project.org] On Behalf Of Bert Gunter > Sent: Thursday, June 1, 2017 12:46 PM > To: Roy Mendelssohn - NOAA Federal <roy.mendelssohn at noaa.gov> > Cc: R-help <r-help at r-project.org> > Subject: Re: [R] Reversing one dimension of an array, in a generalized case > > How about this: > > f <- function(a,wh){ ## a is the array; wh is the index to be reversed > l<- lapply(dim(a),seq_len) > l[[wh]]<- rev(l[[wh]]) > do.call(`[`,c(list(a),l)) > } > > ## test > z <- array(1:120,dim=2:5) > > ## I omit the printouts > > f(z,2) > > f(z,3) > > > Cheers, > Bert > > Bert Gunter > > "The trouble with having an open mind is that people keep coming along > and sticking things into it." > -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) > > > On Thu, Jun 1, 2017 at 9:51 AM, Roy Mendelssohn - NOAA Federal > <roy.mendelssohn at noaa.gov> wrote: >> Hi All: >> >> I have been looking for an elegant way to do the following, but haven't found it, I have never had a good understanding of any of the "apply" functions. >> >> A simplified idea is I have an array, say: >> >> junk(5, 10, 3) >> >> where (5, 10, 3) give the dimension sizes, and I want to reverse the second dimension, so I could do: >> >> junk1 <- junk[, rev(seq_len(10), ] >> >> but what I am after is a general function that will do that where the array could be two, three or four dimensions, and I pass to the function which dimension I want to reverse, that is the function can not assume the number of dimensions of the array nor which dimension to reverse. >> >> For example, if i try: >> >> junk1 <- apply(junk, 2, rev) >> >> junk1 comes out as two-dimensional, not three-dimensional. >> >> It is probably something obvious but I am not getting it. >> >> Thanks for any help. >> >> -Roy >> >> >> ********************** >> "The contents of this message do not reflect any position of the U.S. Government or NOAA." >> ********************** >> Roy Mendelssohn >> Supervisory Operations Research Analyst >> NOAA/NMFS >> Environmental Research Division >> Southwest Fisheries Science Center >> ***Note new street address*** >> 110 McAllister Way >> Santa Cruz, CA 95060 >> Phone: (831)-420-3666 >> Fax: (831) 420-3980 >> e-mail: Roy.Mendelssohn at noaa.gov www: http://www.pfeg.noaa.gov/ >> >> "Old age and treachery will overcome youth and skill." >> "From those who have been given much, much will be expected" >> "the arc of the moral universe is long, but it bends toward justice" -MLK Jr. >> >> ______________________________________________ >> 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. > > ______________________________________________ > 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.
Ismail SEZEN
2017-Jun-01 19:40 UTC
[R] Reversing one dimension of an array, in a generalized case
And my 2 cents, Rev <- function(x, margin) { newdim <- rep("", length(dim(x))) newdim[margin] <- paste(dim(x), ":1", sep = "")[margin] z <- eval(parse(text = gettextf("x[%s,drop = F]", paste(newdim, sep = "", collapse = ",")))) class(z) <- oldClass(x) return(z) } z <- array(1:24,dim=2:4) dim(f(z, 3)) # 2 3 4 dim(f2(z, 3)) # 3 4 2 dim(Rev(z, 3)) # 2 3 4 dim(revdim(z,3)) # 2 3 4 microbenchmark::microbenchmark(f(z, 3), Rev(z, 3), revdim(z,3), f2(z,3)) Unit: microseconds expr min lq mean median uq max neval f(z, 3) 6.356 7.6090 9.74268 9.3285 11.2325 35.571 100 Rev(z, 3) 161.079 166.9660 175.26906 172.1450 176.8130 273.078 100 revdim(z, 3) 5.011 6.1300 7.88565 7.5695 9.0500 21.301 100 f2(z, 3) 68.454 71.6815 82.85703 81.6700 87.9285 126.496 100 and strangely, all.equal(f(z, 3), Rev(z, 3), revdim(z,3), f2(z,3)) [1] TRUE ?> On 1 Jun 2017, at 22:00, Bert Gunter <bgunter.4567 at gmail.com> wrote: > > ?? > >> z <- array(1:24,dim=2:4) >> all.equal(f(z,3),f2(z,3)) > > [1] "Attributes: < Component ?dim?: Mean relative difference: 0.4444444 >" > [2] "Mean relative difference: 0.6109091" > > In fact, > >> dim(f(z,3)) > [1] 2 3 4 > >> dim(f2(z,3)) > [1] 3 4 2 > > Have I made some sort of stupid error here? Or have I misunderstood > what was wanted? > > Cheers, > Bert > > > > > Bert Gunter > > "The trouble with having an open mind is that people keep coming along > and sticking things into it." > -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) > > > On Thu, Jun 1, 2017 at 11:34 AM, David L Carlson <dcarlson at tamu.edu> wrote: >> Here is an alternative approach using apply(). Note that with apply() you are reversing rows or columns not indices of rows or columns so apply(junk, 2, rev) reverses the values in each column not the column indices. We actually need to use rev() on everything but the index we are interested in reversing: >> >> f2 <- function(a, wh) { >> dims <- seq_len(length(dim(a))) >> dims <- setdiff(dims, wh) >> apply(apply(a, dims, rev), dims, t) >> } >> >> # Your example >> j1 <- junk[ , rev(1:10), ] >> j2 <- f2(junk, 2) >> all.equal(j1, j2) >> # [1] TRUE >> >> # Bert's example >> z1 <- f(z, 2) >> z2 <- f2(z, 2) >> all.equal(z1, z2) >> # [1] TRUE >> >> ------------------------------------- >> David L Carlson >> Department of Anthropology >> Texas A&M University >> College Station, TX 77840-4352 >> >> >> >> >> >> >> -----Original Message----- >> From: R-help [mailto:r-help-bounces at r-project.org] On Behalf Of Bert Gunter >> Sent: Thursday, June 1, 2017 12:46 PM >> To: Roy Mendelssohn - NOAA Federal <roy.mendelssohn at noaa.gov> >> Cc: R-help <r-help at r-project.org> >> Subject: Re: [R] Reversing one dimension of an array, in a generalized case >> >> How about this: >> >> f <- function(a,wh){ ## a is the array; wh is the index to be reversed >> l<- lapply(dim(a),seq_len) >> l[[wh]]<- rev(l[[wh]]) >> do.call(`[`,c(list(a),l)) >> } >> >> ## test >> z <- array(1:120,dim=2:5) >> >> ## I omit the printouts >> >> f(z,2) >> >> f(z,3) >> >> >> Cheers, >> Bert >> >> Bert Gunter >> >> "The trouble with having an open mind is that people keep coming along >> and sticking things into it." >> -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) >> >> >> On Thu, Jun 1, 2017 at 9:51 AM, Roy Mendelssohn - NOAA Federal >> <roy.mendelssohn at noaa.gov> wrote: >>> Hi All: >>> >>> I have been looking for an elegant way to do the following, but haven't found it, I have never had a good understanding of any of the "apply" functions. >>> >>> A simplified idea is I have an array, say: >>> >>> junk(5, 10, 3) >>> >>> where (5, 10, 3) give the dimension sizes, and I want to reverse the second dimension, so I could do: >>> >>> junk1 <- junk[, rev(seq_len(10), ] >>> >>> but what I am after is a general function that will do that where the array could be two, three or four dimensions, and I pass to the function which dimension I want to reverse, that is the function can not assume the number of dimensions of the array nor which dimension to reverse. >>> >>> For example, if i try: >>> >>> junk1 <- apply(junk, 2, rev) >>> >>> junk1 comes out as two-dimensional, not three-dimensional. >>> >>> It is probably something obvious but I am not getting it. >>> >>> Thanks for any help. >>> >>> -Roy >>> >>> >>> ********************** >>> "The contents of this message do not reflect any position of the U.S. Government or NOAA." >>> ********************** >>> Roy Mendelssohn >>> Supervisory Operations Research Analyst >>> NOAA/NMFS >>> Environmental Research Division >>> Southwest Fisheries Science Center >>> ***Note new street address*** >>> 110 McAllister Way >>> Santa Cruz, CA 95060 >>> Phone: (831)-420-3666 >>> Fax: (831) 420-3980 >>> e-mail: Roy.Mendelssohn at noaa.gov www: http://www.pfeg.noaa.gov/ >>> >>> "Old age and treachery will overcome youth and skill." >>> "From those who have been given much, much will be expected" >>> "the arc of the moral universe is long, but it bends toward justice" -MLK Jr. >>> >>> ______________________________________________ >>> 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. >> >> ______________________________________________ >> 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. > > ______________________________________________ > 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.
Apparently Analagous Threads
- Reversing one dimension of an array, in a generalized case
- Reversing one dimension of an array, in a generalized case
- Reversing one dimension of an array, in a generalized case
- Reversing one dimension of an array, in a generalized case
- Reversing one dimension of an array, in a generalized case