[R] Create a numeric series in an efficient way

@vi@e@gross m@iii@g oii gm@ii@com @vi@e@gross m@iii@g oii gm@ii@com
Fri Jun 14 06:03:58 CEST 2024


Bert,

I think you read my message differently than I expected. I approached the request as an exercise in evaluating various ways something can be done and maybe choosing a simple one or choosing a more general one as needed.

I provided some solutions along the lines you mentioned and THEN also suggested that there can be a general purpose way to use or write a function that will take one of several way to specify what you want and do a calculation. This would be needed for really miscellaneous data with no logic or ordering such as an analysis of how many people in some mailing list had each last name in that population.

If you had a vector like:
Names <- c("Smith", "Jones", "Gunter")

And another like:

Counts <- c(5, 3, 1)

Then calling a function you created with a name like:

Mult_repeat(Names, Counts)

Should output something like c("Smith", "Smith","Smith","Smith","Smith","Jones","Jones","Jones","Gunter",)

The innards of such a function would work for such a completely general case and need not be discussed but obviously some form of loop, perhaps implicit, could do it. And, it could also do the simpler case shown as an example, albeit there are short elegant ways to do that. But a sorted deck of cards that is shuffled, would not ...

The other solution I alluded to might be to make a function with a ... specification that takes any number of arguments and could be called as in:

Mult_repeat("Smith", 5,  "Jones",3, "Gunter", 1)

It would simply look at something like unlist(list(...)) and take two arguments at a time and call rep() with those and keep appending it to an empty list or if needed a vector.

What I offered was a set of APPROACHES to consider depending on what you needed.

One I did not mention but considered was using one of the "map" functions in the purr package to do this by effectively taking two vectors as described above and calling rep() repeatedly on pairs and consolidating the results:

The following one liner handles the case mentioned with me substituting a 4 for the 84 for brevity:

> unlist(purrr::map2(.x=1:13, .y=rep(4,13), .f=rep))
 [1]  1  1  1  1  2  2  2  2  3  3  3  3  4  4  4  4  5  5  5  5  6  6  6  6  7  7  7  7  8  8  8  8  9  9  9  9 10 10 10 10
[41] 11 11 11 11 12 12 12 12 13 13 13 13

It would work as easily on my example from above:

> Names <- c("Smith", "Jones", "Gunter")
> Counts <- c(5, 3, 1)
> unlist(purrr::map2(.x=Names, .y=Counts, .f=rep))
[1] "Smith"  "Smith"  "Smith"  "Smith"  "Smith"  "Jones"  "Jones"  "Jones"  "Gunter"

If that remains unclear, I am doing something wrong today.

It is nice to see alternatives but some people just want one answer. Read my first message and see I also gave ones like yours.

-----Original Message-----
From: Bert Gunter <bgunter.4567 using gmail.com> 
Sent: Thursday, June 13, 2024 10:42 PM
To: avi.e.gross using gmail.com
Cc: Francesca PANCOTTO <francesca.pancotto using unimore.it>; r-help using r-project.org
Subject: Re: [R] Create a numeric series in an efficient way

"If you want a much more compact solution that handles arbitrary pairs of
"what to copy", number_of_copies, you can write a function  that evaluates
two arguments at a time or takes two vectors as arguments like this one I
wrote quickly and crudely:"

Please! -- The "times" argument of rep can be a vector that does exactly this:

times
an integer-valued vector giving the (non-negative) number of times to
repeat each element if of length length(x), or to repeat the whole
vector if of length 1.

In future, please read the Help files carefully before dispensing such "advice."

-- Bert


On Thu, Jun 13, 2024 at 7:04 PM <avi.e.gross using gmail.com> wrote:
>
> For the particular example you asked for, consider the "each" you can use
> with rep()
>
> rep(1:13, each=84)
>
> This is what it does for a shorter version of 4 each:
>
> > rep(1:13, each=4)
>  [1]  1  1  1  1  2  2  2  2  3  3  3  3  4  4  4  4  5  5  5  5  6  6  6  6
> 7  7  7  7  8  8  8  8  9  9  9  9 10 10 10 10
> [41] 11 11 11 11 12 12 12 12 13 13 13 13
>
>
> For another variant, make 84 copies of 1:13 and sort that as you happen to
> want the numbers in order.
>
> sort(rep(1:13, each=84))
>
> The output is the same.
>
> If you want a much more compact solution that handles arbitrary pairs of
> "what to copy", number_of_copies, you can write a function  that evaluates
> two arguments at a time or takes two vectors as arguments like this one I
> wrote quickly and crudely:
>
> rep_many <- function(items, counts) {
>   result <- c()
>   for (index in 1:length(items)) {
>     result <- c(result, rep(items[index], counts[index]))
>   }
>   return(result)
>   }
>
> rep_many(1:13, rep(84,13))
>
>
> The same ideas can be used using a data.frame or functional programming
> methods but the above is simple enough to flexibly create two vectors
> specifying how much of each.
>
> You said you found a solution, so you may want to share what you chose
> already.
>
>
>
>
> -----Original Message-----
> From: R-help <r-help-bounces using r-project.org> On Behalf Of Francesca PANCOTTO
> via R-help
> Sent: Thursday, June 13, 2024 10:42 AM
> To: r-help using r-project.org
> Subject: [R] Create a numeric series in an efficient way
>
> Dear Contributors
> I am trying to create a numeric series with repeated numbers, not difficult
> task, but I do not seem to find an efficient way.
>
> This is my solution
>
> blocB <- c(rep(x = 1, times = 84), rep(x = 2, times = 84), rep(x = 3, times
> = 84), rep(x = 4, times = 84), rep(x = 5, times = 84), rep(x = 6, times =
> 84), rep(x = 7, times = 84), rep(x = 8, times = 84), rep(x = 9, times =
> 84), rep(x = 10, times = 84), rep(x = 11, times = 84), rep(x = 12, times =
> 84), rep(x = 13, times = 84))
>
> which works but it is super silly and I need to create different variables
> similar to this, changing the value of the repetition, 84 in this case.
> Thanks for any help.
>
>
> F.
>
>         [[alternative HTML version deleted]]
>
> ______________________________________________
> R-help using 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 using 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.



More information about the R-help mailing list