I have data similar to this:
library(data.table)
library(stringr)
dt <- data.table(id=1:20,
month_1=rep(sample(1:12, 20, replace = T)),
month_2=rep(sample(1:12, 20, replace = T)),
month_3=rep(sample(1:12, 20, replace = T)),
month_4=rep(sample(1:12, 20, replace = T)),
year_1=rep(sample(2010:2020, 20, replace = T)),
year_2=rep(sample(2010:2020, 20, replace = T)),
year_3=rep(sample(2010:2020, 20, replace = T)),
year_4=rep(sample(2010:2020, 20, replace = T)))
and I am trying execute these 4 commands
dt[,date_1:= as.Date(paste0(year_1, "-", str_pad(month_1, 2, pad = "0"), "-", 01))]
dt[,date_2:= as.Date(paste0(year_2, "-", str_pad(month_1, 2, pad = "0"), "-", 01))]
dt[,date_3:= as.Date(paste0(year_3, "-", str_pad(month_1, 2, pad = "0"), "-", 01))]
dt[,date_4:= as.Date(paste0(year_4, "-", str_pad(month_1, 2, pad = "0"), "-", 01))]
How can I do this using a for loop?
I have tried:
for (i in 1:4){
dt[,date_i:= as.Date(paste0(year_i, "-", str_pad(month_i, 2, pad = "0"), "-", 01))]
}
But get the error:
Error in paste0(year_i, "-", str_pad(month_i, 2, pad = "0"), "-", 1) : object 'year_i' not found
CodePudding user response:
Fixing the broken loop without major changes:
for (i in 1:4) {
date_var = paste0("date_", i)
year_var = paste0("year_", i)
month_var = paste0("month_", i)
dt[, (date_var) := as.Date(paste0(get(year_var), "-", str_pad(get(month_var), 2, pad = "0"), "-", 01))]
}
Refactoring a bit and removing the stringr dependency:
for (i in 1:4) {
year_var = paste0("year_", i)
month_var = paste0("month_", i)
set(
x = dt,
j = paste0("date_", i),
value = as.Date(paste(dt[[year_var]], dt[[month_var]], "1"), "%Y %m %d")
)
}
CodePudding user response:
Or with lapply
:
i <- 1:4
dt[,paste0("date_i",i):=lapply(i,function(i) as.Date(paste0(get(paste0("year_",i)), "-", str_pad(month_1, 2, pad = "0"), "-", 01)))][]
CodePudding user response:
One way to solve your problem:
i = 1:4
dt[, paste0("date_", i) := Map(\(x,y) as.Date(sprintf("%d-d-01", x, y)),
mget(paste0("year_", i)),
mget(paste0("month_", i)))]