函数在lapply中返回一个函数-嵌套的lapply?

时间:2018-08-09 00:16:21

标签: r function data.table lapply factors

我以为我对代码很满意,直到遇到 lapply 函数的问题。 我用dput输出样本。请注意,我使用的是data.table而不是data.frame。

full_data <- structure(list(FireplaceQu = c("Gd", "Gd", "TA", "TA", "Gd", 
"None", "Gd", "Gd", "None", "None", "None", "None", "Gd", "Gd", 
"Gd", "None"), BsmtQual = c("TA", "Gd", "Gd", "TA", "Gd", "TA", 
"Ex", "TA", "TA", "TA", "TA", "Ex", "TA", "Ex", "Ex", "Gd"), 
    CentralAir = c("Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "N", 
    "N", "Y", "Y", "Y", "Y", "Y", "Y")), .Names = c("FireplaceQu", 
"BsmtQual", "CentralAir"), class = "data.frame", row.names = c(NA, 
-16L))

library(data.table)
setDT(full_data)


cols = c('FireplaceQu', 'BsmtQual', 'CentralAir')

FireplaceQu=c('None','Po','Fa','TA','Gd','Ex')
BsmtQual=c('None','Po','Fa','TA','Gd','Ex')
CentralAir=NA

cust_levels <- list(FireplaceQu, BsmtQual, CentralAir)

# I modified a function from SO to sort based on set levels instead of by using default sort function.
# https://stackoverflow.com/questions/38620424/label-encoder-functionality-in-r
# function which returns function which will encode vectors with values  of 'vec' 
lev_index = 1
label_encoder = function(vec){
    levels = cust_levels[[lev_index]]
    lev_index = lev_index + 1
    function(x){
        match(x, levels)
    }
}

full_data[, (cols) := lapply(.SD, lapply(.SD, label_encoder)), .SDcols = cols]

我知道我可以在for循环中使用它,但是我想我会尝试使用 lapply 函数。我对如何将此函数与以返回值作为函数且需要进行评估的函数一起使用感到困惑。

我最终希望创建基于cust_levels的顺序排序的整数值。如果我能摆脱lev_index的话,那就好了!

示例输入:

FireplaceQu BsmtQual CentralAir
         None       Gd          Y
           TA       Gd          Y
           TA       Gd          Y
           Gd       TA          Y

示例输出:

FireplaceQu BsmtQual CentralAir
         1       5          NA
         4       5          NA
         4       5          NA
         5       4          NA

1 个答案:

答案 0 :(得分:2)

您可以使用mapply进行此操作:

full_data[, (cols) := mapply(match, .SD, cust_levels, SIMPLIFY = FALSE), .SDcols = cols]

# > full_data
#     FireplaceQu BsmtQual CentralAir
#  1:           5        4         NA
#  2:           5        5         NA
#  3:           4        5         NA
#  4:           4        4         NA
#  5:           5        5         NA
#  6:           1        4         NA
#  7:           5        6         NA
#  8:           5        4         NA
#  9:           1        4         NA
# 10:           1        4         NA
# 11:           1        4         NA
# 12:           1        6         NA
# 13:           5        4         NA
# 14:           5        6         NA
# 15:           5        6         NA
# 16:           1        5         NA