With data.table
, we can specify the .SDcols
to select the ‘DR’ columns or ‘date_cols’ and assign back the output to those, then instead of using rowwise matching, use a row/column indexing to extract the values to create the ‘Result’
library(data.table)
# get the column names that starts with DR
dr_names <- grep("^DR", names(df1), value = TRUE)
# get the columns that contains date as substring
date_names <- grep("date", names(df1), value = TRUE)
# setDT - converts the data.frame to data.table
# .SDcols - specify the dr_names, date_names, loop over those
# with lapply, apply the functions and assign (`:=`) back to
# same columns
setDT(df1)[, (dr_names) := lapply(.SD, function(x) coef - x), .SDcols = dr_names
][, (date_names) := lapply(.SD, as.IDate), .SDcols = date_names
][, datedif := date2 - date1]
# rename with setnames
setnames(df1, dr_names, sub("([A-Z])0+", "\\1", dr_names))
# Extract the corresponding 'DRM' column based on the value from
# datediff and match it with the DRM column names
# using a row/column indexing
# return the Result and coef columns
Output2 <- df1[, .(coef, Result = as.matrix(.SD)[cbind(.I,
match(paste0('DRM', datedif), names(.SD)))]),
.SDcols = patterns("^DRM\\d+")]
Output2[is.na(Result), Result := coef]
-output
> Output2
coef Result
<num> <num>
1: 8 6
15
solved How adjust code functionality to specifications using data.table function