Last active
December 12, 2019 11:15
-
-
Save artemklevtsov/60a4d63b911791d7f1cc7fd3dc489e85 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#' @title Перекодировка столбцов таблицы | |
#' @param x Вектор или таблица. | |
#' @param enc Строка, содержащая название кодировки. Если параметр не задан, используется автоопределение кодировки. | |
#' @param defqult Строка, содержащая кодировку по умолчанию, которая будет использована в случае, если автоматически определить кодировку не удалось. | |
#' @return Исходный объект, с перекодированными элементами. | |
#' @details | |
#' Функция изменяет объект на месте, то есть будет изменён переданный объект. | |
#' Для определения кодировки используется пакет `Ruchardet`. | |
#' Предполагается, что вектор (столбец) содердит только одну кодировку. | |
#' @importFrom data.table set setDT | |
#' @importFrom uchardet detect_str_enc | |
#' @importFrom stringi stri_enc_mark stri_encode | |
#' @author Artem Klevtsov | |
convert_encoding <- function(x, ...) { | |
UseMethod("convert_encoding") | |
} | |
convert_encoding.default <- function(x, ...) { | |
stop("Not implemented. Please implement S3-method for the appropriate class.") | |
} | |
convert_encoding.character <- function(x, enc, default = "CP1251") { | |
# Находим индексы вектора с нативной кодировкой | |
ind <- which(stringi::stri_enc_mark(x) == "native") | |
# Перекодируем только, если есть элементы в нативной кодировке | |
if (length(ind) > 0L) { | |
# Если кодировка не указана | |
if (missing(enc)) { | |
# Копируем элементы в нативной кодировке во временный вектор | |
tmp <- paste(x[ind], collapse = " ") | |
# Определяем кодировку | |
enc <- uchardet::detect_str_enc(tmp) | |
if (is.na(enc)) { | |
warning("Не удалось определить кодировку элементов, считаем по умолчанию ", default) | |
enc <- default | |
} | |
} | |
x[ind] <- stringi::stri_encode(x[ind], enc, "UTF-8") | |
} | |
return(x) | |
} | |
convert_encoding.data.table <- function(x, enc, default = "CP1251") { | |
# Преобразуем в `data.table` при необходимости | |
if (!is.data.table(x)) setDT(x) | |
# Перекодируем имена столбцов | |
setnames(x, convert_encoding(names(x), enc = enc, default = default)) | |
# Автоматически определяем character-столбцы | |
cols <- which(sapply(x, is.character), useNames = FALSE) | |
# Если список столбцов пустой, выходим | |
if (length(cols) == 0L) | |
return(invisible(NULL)) | |
# Цикл в данном случае также быстр как и lapply(.SD, ...), но более экономичен по памяти | |
for (col in cols) | |
set(x, j = col, value = convert_encoding(x[[col]], enc = enc, default = default)) | |
return(invisible(x)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment