Home > Software engineering >  Looping through columns of different dimensions in R
Looping through columns of different dimensions in R

Time:12-17

I have the following data frame

emp.data <- data.frame(
    emp_name = c("Rick","Dan","Michelle","Ryan","Gary"),
    mon_expiry = c(211.2,442.1,114.2,22,29), 
    stringsAsFactors = FALSE
)

I have another data frame

Time <- data.frame(matrix(vector(),ncol=361))
colnames(Time) <-c(0:360)

For each of the emp_name in emp. data, I want to loop through column headers in Time and subtract it from mon_expiry. For eg, for Rick, I want to create a new row that contains values (211.2 - 0), (211.2 - 1), (211.2 - 2),... so on till (211.2 - 360). A new data frame has to be created by repeating for all emp_name.

Output

Desired Output

I am new to R and struggling to get through this.

CodePudding user response:

You can use rowwise to make list-columns, and then unnest:

library(tidyverse)

tibble(emp.data) %>% 
  rowwise() %>% 
  mutate(mon_expiry = list(mon_expiry - 0:360)) %>% 
  unnest_wider(mon_expiry, names_sep = "_")

# A tibble: 5 × 362
  emp_name mon_expiry_1 mon_expiry_2 mon_expiry_3 mon_expiry_4 mon_expiry_5
  <chr>           <dbl>        <dbl>        <dbl>        <dbl>        <dbl>
1 Rick             211.         210.         209.         208.         207.
2 Dan              442.         441.         440.         439.         438.
3 Michelle         114.         113.         112.         111.         110.
4 Ryan              22           21           20           19           18 
5 Gary              29           28           27           26           25 # ...

CodePudding user response:

library(tidyverse)

new_rows <- emp.data$mon_expiry %>%
  map(~ . - as.numeric(names(Time)) %>% t())

final_df <- bind_cols(emp.data, map_dfr(new_rows, ~ as.data.frame(.) %>% set_names(str_c("X", seq_along(names(Time))))))


as_tibble(final_df) 
#> # A tibble: 5 × 363
#>   emp_name mon_expiry    X1    X2    X3    X4    X5    X6    X7    X8    X9
#>   <chr>         <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Rick           211.  211.  210.  209.  208.  207.  206.  205.  204.  203.
#> 2 Dan            442.  442.  441.  440.  439.  438.  437.  436.  435.  434.
#> 3 Michelle       114.  114.  113.  112.  111.  110.  109.  108.  107.  106.
#> 4 Ryan            22    22    21    20    19    18    17    16    15    14 
#> 5 Gary            29    29    28    27    26    25    24    23    22    21 
#> # … with 352 more variables: X10 <dbl>, X11 <dbl>, X12 <dbl>, …

Created on 2021-12-17 by the reprex package (v2.0.1)

CodePudding user response:

new_df <- cbind(emp.data, outer(emp.data[,2], 1:360, '-'))

Printing the first 5 columns

new_df[,1:5]

  emp_name mon_expiry     1     2     3
1     Rick      211.2 210.2 209.2 208.2
2      Dan      442.1 441.1 440.1 439.1
3 Michelle      114.2 113.2 112.2 111.2
4     Ryan       22.0  21.0  20.0  19.0
5     Gary       29.0  28.0  27.0  26.0

CodePudding user response:

data.table

emp.data <- data.frame(
  emp_name = c("Rick", "Dan", "Michelle", "Ryan", "Gary"),
  mon_expiry = c(211.2, 442.1, 114.2, 22, 29),
  stringsAsFactors = FALSE
)

Time <- 0:360
library(data.table)

col_names <- paste0("x", 0:360, sep = "")
setDT(emp.data)[, (col_names) := lapply(Time, function(x) mon_expiry - x)][]

#>    emp_name mon_expiry    x0    x1    x2    x3    x4    x5    x6    x7    x8
#> 1:     Rick      211.2 211.2 210.2 209.2 208.2 207.2 206.2 205.2 204.2 203.2
#> 2:      Dan      442.1 442.1 441.1 440.1 439.1 438.1 437.1 436.1 435.1 434.1
#> 3: Michelle      114.2 114.2 113.2 112.2 111.2 110.2 109.2 108.2 107.2 106.2
#> 4:     Ryan       22.0  22.0  21.0  20.0  19.0  18.0  17.0  16.0  15.0  14.0
#> 5:     Gary       29.0  29.0  28.0  27.0  26.0  25.0  24.0  23.0  22.0  21.0

Created on 2021-12-17 by the reprex package (v2.0.1)

  •  Tags:  
  • r
  • Related