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
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)