[R] Reduce woes

Stefan Kruger stefan.kruger at gmail.com
Thu Jul 28 12:55:54 CEST 2016


David - many thanks for your response.

What I tried to do was to turn

data <- list(one = c(1, 1), three = c(3), two = c(2, 2))

into

result <- list(one = 2, three = 1, two = 2)

that is creating a new list which has the same names as the first, but
where the values are the vector lengths.

I know there are many other (and better) trivial ways of achieving this -
my aim is less the task itself, and more figuring out if this can be done
using Reduce() in the fashion I showed in the other examples I gave. It's a
building block of doing map-filter-reduce type pipelines that I'd like to
understand how to do in R.

Fumbling in the dark, I tried:

Reduce(function(acc, item) { setNames(c(acc, length(data[item])), item },
names(data), accumulate=TRUE)

but setNames sets all the names, not adding one - and acc is still a
vector, not a list.

It looks like 'lambda.tools.fold()' and possibly 'purrr.reduce()' aim at
doing what I'd like to do - but I've not been able to figure out quite how.

Thanks

Stefan



On 27 July 2016 at 20:35, David Winsemius <dwinsemius at comcast.net> wrote:

>
> > On Jul 27, 2016, at 8:20 AM, Stefan Kruger <stefan.kruger at gmail.com>
> wrote:
> >
> > Hi -
> >
> > I'm new to R.
> >
> > In other functional languages I'm familiar with you can often seed a call
> > to reduce() with a custom accumulator. Here's an example in Elixir:
> >
> > map = %{"one" => [1, 1], "three" => [3], "two" => [2, 2]}
> > map |> Enum.reduce(%{}, fn ({k,v}, acc) -> Map.update(acc, k,
> > Enum.count(v), nil) end)
> > # %{"one" => 2, "three" => 1, "two" => 2}
> >
> > In R-terms that's reducing a list of vectors to become a new list mapping
> > the names to the vector lengths.
> >
> > Even in JavaScript, you can do similar things:
> >
> > list = { one: [1, 1], three: [3], two: [2, 2] };
> > var result = Object.keys(list).reduceRight(function (acc, item) {
> >  acc[item] = list[item].length;
> >  return acc;
> > }, {});
> > // result == { two: 2, three: 1, one: 2 }
> >
> > In R, from what I can gather, Reduce() is restricted such that any init
> > value you feed it is required to be of the same type as the elements of
> the
> > vector you're reducing -- so I can't build up. So whilst I can do, say
> >
> >> Reduce(function(acc, item) { acc + item }, c(1,2,3,4,5), 96)
> > [1] 111
> >
> > I can't use Reduce to build up a list, vector or data frame?
> >
> > What am I missing?
> >
> > Many thanks for any pointers,
>
> This builds a list:
>
> > Reduce(function(acc, item) { c(acc , item) }, c(1,2,3,4,5), 96,
> accumulate=TRUE)
> [[1]]
> [1] 96
>
> [[2]]
> [1] 96  1
>
> [[3]]
> [1] 96  1  2
>
> [[4]]
> [1] 96  1  2  3
>
> [[5]]
> [1] 96  1  2  3  4
>
> [[6]]
> [1] 96  1  2  3  4  5
>
> But you are not saying what you want. The other examples were doing
> something with names but you provided no names for the R example.
>
> This would return a list of named vectors:
>
> > Reduce(function(acc, item) { setNames( c(acc,item), 1:(item+1))  },
> c(1,2,3,4,5), 96, accumulate=TRUE)
> [[1]]
> [1] 96
>
> [[2]]
>  1  2
> 96  1
>
> [[3]]
>  1  2  3
> 96  1  2
>
> [[4]]
>  1  2  3  4
> 96  1  2  3
>
> [[5]]
>  1  2  3  4  5
> 96  1  2  3  4
>
> [[6]]
>  1  2  3  4  5  6
> 96  1  2  3  4  5
>
>
>
>
> > Stefan
> >
> >
> >
> > --
> > Stefan Kruger <stefan.kruger at gmail.com>
> >
> >       [[alternative HTML version deleted]]
> >
> > ______________________________________________
> > 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 Winsemius
> Alameda, CA, USA
>
>


-- 
Stefan Kruger <stefan.kruger at gmail.com>

	[[alternative HTML version deleted]]



More information about the R-help mailing list