using base R to convert list to dataframe while setting its class type and column names
Solution 1:
Assuming you want this to be a programmatic venture:
d2 <- setNames(data.frame(d), nm)
str(d2)
# 'data.frame': 3 obs. of 4 variables:
# $ num : num 1 2 3
# $ date : chr "20210111" "20220122" "20220302"
# $ relation: chr "father" "mather" "brother"
# $ chara : chr "hello" "world" "again"
From here,
isdate <- type == "Date"
funs <- mget(paste0("as.", type), inherits = TRUE)
str(funs) # list of functions
# List of 4
# $ as.integer :function (x, ...)
# $ as.Date :function (x, ...)
# $ as.factor :function (x)
# $ as.character:function (x, ...)
d2[isdate] <- Map(function(f, ...) f(...), funs[isdate], d2[isdate], list(format = "%Y%m%d"))
d2[!isdate] <- Map(function(f, ...) f(...), funs[!isdate], d2[!isdate])
str(d2)
# 'data.frame': 3 obs. of 4 variables:
# $ num : int 1 2 3
# $ date : Date, format: "2021-01-11" "2022-01-22" "2022-03-02"
# $ relation: Factor w/ 3 levels "brother","father",..: 2 3 1
# $ chara : chr "hello" "world" "again"
Solution 2:
You could use structure()
. Currently your Date
variable isn't very handy and you need to do d[[2]] <- as.Date(d[[2]], format='%Y%m%d')
beforehand.
r <- structure(Map(\(x, y, z) eval(parse(text=x)), sprintf('as.%s(y)', type), d),
class="data.frame",
row.names=c(NA, -3L),
names=nm)
r
# num date relation chara
# 1 1 2021-01-11 father hello
# 2 2 2022-01-22 mather world
# 3 3 2022-03-02 brother again
str(r)
# 'data.frame': 3 obs. of 4 variables:
# $ num : int 1 2 3
# $ date : Date, format: "2021-01-11" ...
# $ relation: Factor w/ 3 levels "brother","father",..: 2 3 1
# $ chara : chr "hello" "world" "again"
Note: R >= 4.1 used.
Data:
d <- list(c(1, 2, 3),
c("20210111", "20220122", "20220302"),
c("father", "mather", "brother"),
c("hello", "world", "again"))
type <- c("integer", "Date", "factor", "character")
nm <- c("num", "date", "relation", "chara")