2017-01-03 4 views
1

Я написал следующий цикл для преобразования входных данных, которые могут быть одно-, двух- или трехзначными числами, во все трехзначные числа; так что входной вектор [7, 8, 9, 10, 11] будет преобразован в выходной вектор [007, 008, 009, 010, 011]. Это мой код:Простая петля для изменения имен файлов не работает

zeroes <- function(id){ 

    for(i in 1:length(id)){ 
     if(id[i] <= 9){ 
      id[i] <- paste("00", id[i], sep = "") 
     } 
     else if(id[i] >= 10 && id[i] <= 99){ 
      id[i] <- paste("0", id[i], sep = "") 
     } 
    } 
id 
} 

Для входного вектора

id <- 50:100 

я получаю следующий результат:

[1] "050" "0051" "0052" "0053" "0054" "0055" "0056" "0057" "0058" "0059" 
[11] "0060" "0061" "0062" "0063" "0064" "0065" "0066" "0067" "0068" "0069" 
[21] "0070" "0071" "0072" "0073" "0074" "0075" "0076" "0077" "0078" "0079" 
[31] "0080" "0081" "0082" "0083" "0084" "0085" "0086" "0087" "0088" "0089" 
[41] "090" "091" "092" "093" "094" "095" "096" "097" "098" "099" 
[51] "00100" 

Так что, похоже, что для удостоверения личности [1] функция работает, то есть ошибка для следующих чисел, но для id [41:50], я получаю правильный вывод снова. Я не мог понять, почему это так, и что я делаю неправильно. Любые предложения приветствуются.

+3

Просто используйте 'sprintf ("% 03i ", id)' – Tensibai

+0

Спасибо за ответ, я тоже это сделал, он работает. Я все еще хочу знать, почему R прослушивает код выше .. –

+0

или если по какой-то причине вы не хотели использовать 'sprintf' и предпочитаете« вставлять »результат вместе, то« paste0 (strrep («0», 3 -nchar (id)), id) ' –

ответ

6

Потому что, когда вы выполняете первую замену на id в своей функции, вектор становится символом (потому что вектор не может хранить числа и символы).

Так zeroes(51) работает отлично:

> zeroes(51) 
[1] "051" 

, но если его второй пункт, он не:

> zeroes(c(50,51)) 
[1] "050" "0051" 

, потому что к тому времени, ваш цикл получает на 51, его на самом деле "51" в кавычках. И это не удается:

> zeroes("51") 
[1] "0051" 

потому, что "51" меньше, чем 9:

> "51"<9 
[1] TRUE 

потому, что R преобразует 9 в "9", а затем делает сравнение символов, так что только "5" сравнивается с «9» и «5» перед «9» в алфавите последовательности сортировки.

Другие языки могут преобразовывать символ «51» в числовой, а затем сравнивать с цифрой 9 и говорить «51» < 9 - это ложь, но R делает это так.

Урок: не перезаписывайте свои векторы ввода! (и использовать sprintf).

+0

Вы можете отбросить слово на принуждение 9 к символу в '' 51 "<9' и, возможно, сказать, потому что' charToRaw ("5") 'действительно меньше, чем' CharToRaw («9») ' – Tensibai

+1

@Tensibai хорошая идея , изложил это сейчас. – Spacedman

+1

Это задокументировано в '?" <"', "(Убывающий) порядок приоритета является символом, сложным, числовым, целым, логическим и необработанным". – Tensibai