tobinz
tobinz

Reputation: 335

Execute vector multiplication in one variable of a tibble

I have a tibble like this, which can be seen as a longitudinal dataset

df <- tibble( T = rep(1:5,each=3), dens = rnorm(15,0,1) )
  

From df, I wish to obtain a new 3-by-5 matrix, so that the first column is the value of dens for T=1; the second column is product of dens[T=1] dens[T=2] so on and so forth.

The expected output is

 new_df <- cbind(df$dens[1:3], dff$dens[1:3]*df$dens[4:6],df$dens[1:3]*df$dens[4:6]*df$dens[7:9],
                  df$dens[1:3]*df$dens[4:6]*df$dens[7:9]*df$dens[10:12],df$dens[1:3]*df$dens[4:6]*df$dens[7:9]*df$dens[10:12]*df$dens[13:15])
  

How this can be done in a tibble more efficiently?

Upvotes: 1

Views: 36

Answers (2)

ThomasIsCoding
ThomasIsCoding

Reputation: 101663

Perhaps a base R option using Reduce could help

> do.call(cbind, Reduce("*", with(df, split(dens, T)), accumulate = TRUE))
           [,1]        [,2]        [,3]       [,4]        [,5]
[1,] -1.2667876 -1.52064920 -2.25924893 2.55495272 -4.02049920
[2,] -0.2854711 -0.23282226  0.08117526 0.01885956 -0.01893413
[3,]  0.2698863 -0.07630793  0.06976650 0.05718294 -0.10454398

Upvotes: 1

akrun
akrun

Reputation: 887213

An option is to do a group by the rowid of 'T' column, get the cumprod of 'dens' and reshape to 'wide' format with pivot_wider

library(dplyr)
library(tidyr)
library(data.table)
df %>%       
   group_by(rn = rowid(T)) %>% 
   mutate(dens = cumprod(dens)) %>%
   ungroup %>%
   pivot_wider(names_from = T, values_from = dens) %>%
   select(-rn)

-output

# A tibble: 3 x 5
#    `1`   `2`    `3`    `4`    `5`
#  <dbl> <dbl>  <dbl>  <dbl>  <dbl>
#1  1.77 2.06   1.53   2.23  -4.41 
#2  1.96 0.414  0.522 -0.175  0.182
#3  1.57 3.18  -3.99  -4.59   6.64 

-checking with OP's expected

cbind(df$dens[1:3], 
       df$dens[1:3]*df$dens[4:6],
       df$dens[1:3]*df$dens[4:6]*df$dens[7:9],
       df$dens[1:3]*df$dens[4:6]*df$dens[7:9]*df$dens[10:12],
       df$dens[1:3]*df$dens[4:6]*df$dens[7:9]*df$dens[10:12]*df$dens[13:15])
#         [,1]      [,2]       [,3]       [,4]       [,5]
#[1,] 1.773718 2.0604976  1.5309983  2.2307720 -4.4127195
#[2,] 1.961222 0.4142233  0.5222992 -0.1748975  0.1820611
#[3,] 1.571597 3.1822827 -3.9931628 -4.5932566  6.6440672

Upvotes: 1

Related Questions