Прокладка с ведущими нулями до общей ширины

Я обрабатываю БД с часовым форматом, например:

HOUR ID
1 2
10 4
5 6
20 6

Я хотел бы поместить нуль в значение с 1 символом и сохранить их в новом столбце с именем NHOUR, например:

NHOUR HOUR ID
01 1 2
10 10 4
05 5 6
20 20 6

До сих пор я борюсь с чем-то вроде (я следую некоторым предложениям, уже предоставленным для ifelse на форуме):

DB$NHOUR<-with(DB,ifelse(nchar(HOUR,type="chars")==1),sprintf("%02d",HOUR),as.numeric(HOUR))

но без успеха! R всегда сообщает, что элемент "да" не указан и т.д.

Как всегда, любые советы приветствуются!

4 ответа

Просто следуя рекомендациям в комментарии @joran,

DB <- data.frame(
HOUR = c(1, 10, 5, 20),
ID = c(2, 4, 6, 6))
NHOUR <- sprintf("%02d",DB$HOUR) # fix to 2 characters 
cbind(NHOUR, DB) # combine old and newdata 
 NHOUR HOUR ID
1 01 1 2
2 10 10 4
3 05 5 6
4 20 20 6

Обновление 2013-01-21 23: 42: 00Z Вдохновленный daroczig тест производительности ниже, и потому, что я хотел попробовать пакет microbenchmark, я обновил этот вопрос с помощью небольшого теста производительности моего собственного сравнения трех различных решений, предложенных в этом потоке.

# install.packages(c("microbenchmark", "stringr"), dependencies = TRUE)
require(microbenchmark)
require(stringr)
SPRINTF <- function(x) sprintf("%02d", x)
FORMATC <- function(x) formatC(x, width = 2,flag = 0)
STR_PAD <- function(x) str_pad(x, width=2, side="left", pad="0")
x <- round(runif(1e5)*10)
res <- microbenchmark(SPRINTF(x), STR_PAD(x), FORMATC(x), times = 15)
## Print results:
print(res)
Unit: milliseconds
 expr min lq median uq max
1 FORMATC(x) 623.53785 629.69005 638.78667 671.22769 679.8790
2 SPRINTF(x) 34.35783 34.81807 35.04618 35.53696 37.1622
3 STR_PAD(x) 116.54969 118.41944 118.97363 120.05729 163.9664
### Plot results:
boxplot(res)


Мне нравится использовать пакет stringr:

DB$NHOUR <- str_pad(DB$HOUR, width=2, side="left", pad="0")


Альтернативное решение:

> formatC(DB$HOUR, width = 2,flag = 0)
[1] "01" "10" "05" "20"

Обновление: Я только что быстро проверил проблему производительности, чтобы документировать этот вопрос

> library(microbenchmark)
> SPRINTF <- function(x) sprintf("%02d", x)
> FORMATC <- function(x) formatC(x, width = 2,flag = 0)
> x <- round(runif(1e5)*10)
> microbenchmark(SPRINTF(x), FORMATC(x), times = 10)
Unit: milliseconds
 expr min lq median uq max
1 FORMATC(x) 688.35430 723.42458 767.06025 780.84768 878.4966
2 SPRINTF(x) 31.29167 31.96052 35.75735 40.54656 147.6805


Подобно stringr, существует stri_pad_left из stringi

library(stringi)
stri_pad_left(str=DB$HOUR, 2, pad="0")
# [1] "01" "10" "05" "20"

Он должен быть почти таким же быстрым. Аналогичные функции заполнения для правой и обеих сторон.

licensed under cc by-sa 3.0 with attribution.