Sprintf в R не считает умлауты

У меня есть вектор символов, и я хочу убедиться, что все элементы вектора имеют одинаковую длину. Поэтому я заполняю короткие элементы пробелами, например:

vec <- c("fjdlksa01dada","rau","sjklf")
x <- sprintf("%-15s", vec)
nchar(x)
# returns
[1] 15 15 15

как ответы на мои Предыдущий вопрос предложен. Это нормально, но, похоже, у него проблемы с умляутами. Например, если мой вектор выглядит так:

vec2 <- c("fjdlksa01dada","rauü","sjklf")
y <- sprintf("%-15s", vec)
nchar(y)
# returns
[1] 15 14 15

Я использую R в Mac OS X (10.6). Как я могу это исправить?

РЕДАКТИРОВАТЬ: обратите внимание, я не собираюсь исправлять вывод nchar, потому что он правильный. Проблема в том, что sprintf теряет умляут.

РЕДАКТИРОВАТЬ: обновить R, изменить локаль DWins - никаких изменений. Но:

vec2 <- c("fjdlksa01dada","rauü","sjklf")
Encoding(vec2)
# returns
[1] "unknown" "UTF-8"   "unknown"

странный.


person Matt Bannert    schedule 15.02.2012    source источник
comment
Невозможно воспроизвести на Mac под управлением 10.5.8/Rv2.14.1 с › Sys.getlocale() = en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US. УТФ-8.   -  person IRTFM    schedule 15.02.2012
comment
Это очень интересно. У вас случайно нет мануала/ссылки по установке других локалей? Кроме того, я должен обновить R, все еще работает 2.13.2.   -  person Matt Bannert    schedule 15.02.2012
comment
Обновление до 2.14.1 не помогло :(   -  person Matt Bannert    schedule 15.02.2012
comment
Сегодня утром на rhelp был задан вопрос, где автор сказал, что у нее те же настройки локали, что и вы. Они нестандартны, поскольку «UTF-8» недействительна, и Брайану Рипли было интересно, как они стали такими. Sys.setlocale() — это функция, используемая для их изменения.   -  person IRTFM    schedule 15.02.2012
comment
Приемлемо ли для вас принудительное кодирование чего-то другого, кроме UTF-8? Как в Encoding(vec2) <- "latin1".   -  person Richie Cotton    schedule 15.02.2012
comment
@ Richie UTF-8 все еще в порядке, но да, это было бы приемлемо :). Пробовал и это. Но когда я это делаю, я получаю странные символы, и как только я их подставляю, вектор возвращается к UTF-8.   -  person Matt Bannert    schedule 15.02.2012


Ответы (2)


Я нашел это на странице ?sprintf:

Если какой-либо элемент fmt или любой символьный аргумент объявлен как UTF-8, элемент результата будет в UTF-8 и будет иметь кодировку, объявленную как UTF-8. В противном случае это будет кодировка текущей локали.

Ввод берет свою локаль из локали Rgui (я думаю); Смотри ниже.

В окнах он, к счастью, уже печатает:

> vec2 <- c("fjdlksa01dada","rauü","sjklf")
> y <- sprintf("%-15s", vec)
> nchar(y)
[1] 15 15 15

Я думаю, что на MacO вы можете добиться этого, открыв R, как показано ниже, но у меня нет Mac, чтобы проверить это:

Rgui --encoding=utf-8
person Bernd Elkemann    schedule 15.02.2012
comment
Думаю, options("encoding") тоже поможет. - person Roman Luštrik; 15.02.2012
comment
хорошая мысль. К сожалению, я уже использую utf-8, в R Studio, по крайней мере, все мои скрипты сохраняются в UTF-8, а моя локаль установлена ​​​​на C/UTF-8/C/C/C/C. Но приятно знать, что в Windows sprintf работает корректно. - person Matt Bannert; 15.02.2012
comment
@ran2 R Студия? Хм. Вы пытались запустить код в Rgui --encoding=utf-8? Если это работает в Rgui, вы знаете, что это ошибка R Studio, и знаете, где искать дополнительные параметры. - person Bernd Elkemann; 15.02.2012
comment
Хм, только что проверил, тот же результат на терминале… так что R Studio здесь не так уж и плоха. - person Matt Bannert; 15.02.2012
comment
В терминале? это не то же самое, что в Rgui, потому что строки сначала передаются через терминал. - person Bernd Elkemann; 15.02.2012
comment
Тем временем понял это и проверил в R gui, к сожалению, тоже не удалось. - person Matt Bannert; 15.02.2012
comment
Если это имеет значение, в Linux тоже не работает (RStudio и терминал, не могу протестировать Rgui) - person nico; 15.02.2012
comment
хм, позвольте мне посмотреть, смогу ли я что-нибудь узнать, у меня здесь есть машина с Linux, так что, по крайней мере, я могу сам протестировать обходные пути, спасибо, Нико, за упоминание об этом. - person Bernd Elkemann; 15.02.2012

Вероятно, есть более чистый способ... но это работает:

sapply(vec, function(x){
      paste(x, paste(rep(" ", 13-nchar(x)), collapse=""), "")
      })

(см. комментарий ниже для [не]-объяснения для 13)

person nico    schedule 15.02.2012
comment
хм, если я запускаю это, все мои элементы имеют длину 17 символов, но я хочу добавлять пробелы только до 15 символов общей длины. Также обратите внимание, что в конце концов меня не интересует длина (только что опубликовал nchar, который вам не нужно считать) — мне нужны сами элементы вектора. - person Matt Bannert; 15.02.2012
comment
@ran2: правда... странно... это, очевидно, работает, заменяя 15 на 13... но я не уверен, почему. Результатом sapply является вектор элементов, а не длина. - person nico; 15.02.2012
comment
+1 за взлом, потому что это помогает. Тем не менее, я хотел бы узнать, как действительно исправить это с помощью sprintf. - person Matt Bannert; 15.02.2012