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