Добавление ведущих нулей с помощью 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
является интерфейсом к функции C printf
. Использование его требует некоторого знания арканы этой базовой функции (см. ссылку). В этом случае важными моментами являются , 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
- еще одна функция форматирования, в основном для создания меток ручной оси. Он работает особенно хорошо для широких диапазонов числа.
на scales
пакет имеет несколько функций, таких как percent
, date_format
и dollar
для специализированных форматов.
расширение на repsonse @goodside это:
в некоторых случаях вы можете добавить строку с нулями (например, коды 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, вектор вернулся с ведущими пробелами, а не 0
s. Это была та же проблема, упомянутая @user1816679 -- и удаление кавычек вокруг 0
или изменение от %d
to %s
тоже не имело значения. FYI, я использую сервер 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, и мелкие детали (особенно поведение при ошибке пользователя) могут зависеть от платформы