Я думал, что поступаю элегантно с кодом, пока не столкнулся с проблемой с функцией ласковый. Я использовал 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, но я подумал, что попробую использовать функцию ласковый. Я не понимаю, как использовать это с функцией, которая возвращает функцию в качестве значения и которую необходимо оценить.
В конечном итоге я хочу создать целочисленные значения, упорядоченные на основе порядка 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
Вы можете сделать это с помощью 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
Итак, можете ли вы дать желаемый результат для этого ввода, чтобы можно было проверить и проверить возможные решения?