Добавление ведущих нулей с помощью R
у меня есть набор данных, который выглядит примерно так:
anim <- c(25499,25500,25501,25502,25503,25504)
sex <- c(1,2,2,1,2,1)
wt <- c(0.8,1.2,1.0,2.0,1.8,1.4)
data <- data.frame(anim,sex,wt)
data
anim sex wt anim2
1 25499 1 0.8 2
2 25500 2 1.2 2
3 25501 2 1.0 2
4 25502 1 2.0 2
5 25503 2 1.8 2
6 25504 1 1.4 2
Я хотел бы добавить ноль перед каждым идентификатором животного:
data
anim sex wt anim2
1 025499 1 0.8 2
2 025500 2 1.2 2
3 025501 2 1.0 2
4 025502 1 2.0 2
5 025503 2 1.8 2
6 025504 1 1.4 2
и ради интереса, что делать, если мне нужно добавить два или три нуля перед идентификатором животного?
8 ответов:
короткая версия: используйте
formatCилиsprintf.
больше вариант:
есть несколько функций, доступных для форматирования чисел, включая добавление ведущих нулей. Какой из них лучше всего зависит от того, какое другое форматирование вы хотите сделать.
пример из вопроса довольно прост, так как все значения имеют одинаковое количество цифр для начала, поэтому давайте попробуем более сложный пример создания полномочия 10 ширина 8 тоже.
anim <- 25499:25504 x <- 10 ^ (0:5)
paste(и это вариантpaste0) часто являются первыми функциями обработки строк, с которыми вы сталкиваетесь. Они на самом деле не предназначены для манипулирования числами, но их можно использовать для этого. В простом случае, когда мы всегда должны добавить один ноль,paste0- лучшее решение.paste0("0", anim) ## [1] "025499" "025500" "025501" "025502" "025503" "025504"для случая, когда есть переменное число цифр в числах, вы должны вручную вычислить, сколько нулей добавить, что достаточно ужасно, что вы должны делать это только из болезненного любопытства.
str_padСstringrработает аналогичноpaste, что делает его более явным, что вы хотите, чтобы проложить вещи.library(stringr) str_pad(anim, 6, pad = "0") ## [1] "025499" "025500" "025501" "025502" "025503" "025504"опять же, он действительно не предназначен для использования с числами, поэтому более сложный случай требует немного подумать. Мы должны просто быть в состоянии сказать " pad с нулями ширина 8", но посмотрите на этот выход:
str_pad(x, 8, pad = "0") ## [1] "00000001" "00000010" "00000100" "00001000" "00010000" "0001e+05"вам нужно установить научное наказание опции так что числа всегда форматируются с использованием фиксированной нотации (а не научной нотации).
library(withr) with_options( c(scipen = 999), str_pad(x, 8, pad = "0") ) ## [1] "00000001" "00000010" "00000100" "00001000" "00010000" "00100000"
stri_padнаstringiработает точно так же, какstr_padСstringr.
formatC- это интерфейс к функции Cprintf. Использование его требует некоторого знания тайн этой базовой функции (см. ссылку). В этом случае важными моментами являются ,formatбудучи"d"для "integer" и A"0"flagдля добавления нулей.formatC(anim, width = 6, format = "d", flag = "0") ## [1] "025499" "025500" "025501" "025502" "025503" "025504" formatC(x, width = 8, format = "d", flag = "0") ## [1] "00000001" "00000010" "00000100" "00001000" "00010000" "00100000"это мое любимое решение, так как легко возиться с изменением ширины, и функция достаточно мощная, чтобы сделать другое форматирование изменения.
sprintfявляется интерфейсом к функции C с тем же именем; какformatCно с другим синтаксисом.sprintf("%06d", anim) ## [1] "025499" "025500" "025501" "025502" "025503" "025504" sprintf("%08d", x) ## [1] "00000001" "00000010" "00000100" "00001000" "00010000" "00100000"главные преимущества
sprintfэто то, что вы можете вставлять форматированные числа в более длинные биты текста.sprintf( "Animal ID %06d was a %s.", anim, sample(c("lion", "tiger"), length(anim), replace = TRUE) ) ## [1] "Animal ID 025499 was a tiger." "Animal ID 025500 was a tiger." ## [3] "Animal ID 025501 was a lion." "Animal ID 025502 was a tiger." ## [5] "Animal ID 025503 was a tiger." "Animal ID 025504 was a lion."см. также goodside это.
для полноты стоит упомянуть другие функции форматирования, которые являются иногда полезно, но не методом добавления нулей.
format, общая функция для форматирования любого вида объекта, с методом для чисел. Он работает немного какformatC, но с другим интерфейсом.
prettyNumэто еще одна функция форматирования, в основном для создания меток тиков оси вручную. Он работает особенно хорошо для широких диапазонов числа.The
scalesпакет имеет несколько функций, таких какpercent,date_formatиdollarдля специальных типов форматов.
расширение на @ goodside repsonse:
в некоторых случаях вы можете заполнить строку нулями (например, коды fips или другие числовые факторы). В OSX / Linux:
> sprintf("%05s", "104") [1] "00104"а потому что
sprintf()вызывает ОС C обсуждали здесь, в Windows 7 Вы получаете другой результат:> sprintf("%05s", "104") [1] " 104"так что на машинах Windows работа вокруг:
> sprintf("%05d", as.numeric("104")) [1] "00104"
str_padСstringrупаковка является альтернативой.anim = 25499:25504 str_pad(anim, width=6, pad="0")
вот еще одна альтернатива для добавления ведущих к 0s строк, таких как CUSIPs который иногда может выглядеть как число и который многие приложения, такие как Excel будет поврежден и удалить ведущие 0s или конвертировать их в научную нотацию.
когда я попробовал ответ, предоставленный @metasequoia, возвращенный вектор имел ведущие пробелы, а не
0s. Это была та же проблема, упомянутая @user1816679 - и удаление кавычек вокруг0или изменение с%dдо%sтоже не имеет значения. К вашему сведению, я использую сервер RStudio, работающий на сервере Ubuntu. Это маленькое двухэтапное решение сработало для меня:
gsub(pattern = " ", replacement = "0", x = sprintf(fmt = "%09s", ids[,CUSIP]))С помощью
%>%функция трубы отmagrittrпакета это может выглядеть так:
sprintf(fmt = "%09s", ids[,CUSIP]) %>% gsub(pattern = " ", replacement = "0", x = .)Я бы предпочел одну функцию, но она работает.
для других обстоятельств, в которых вы хотите, чтобы числовая строка была согласованной, я сделал функцию.
кто-то может найти это полезным:
idnamer<-function(x,y){#Alphabetical designation and number of integers required id<-c(1:y) for (i in 1:length(id)){ if(nchar(id[i])<2){ id[i]<-paste("0",id[i],sep="") } } id<-paste(x,id,sep="") return(id) } idnamer("EF",28)извините за форматирование.
вот обобщаемая базовая функция R:
pad_left <- function(x, len = 1 + max(nchar(x)), char = '0'){ unlist(lapply(x, function(x) { paste0( paste(rep(char, len - nchar(x)), collapse = ''), x ) })) } pad_left(1:100)мне нравится
sprintfно он поставляется с оговорками, как:однако фактическая реализация будет следовать стандарту C99 и мелкие детали (особенно поведение при ошибке пользователя) могут зависеть от платформы
Comments