Baştaki sıfırlar nasıl eklenir?


352

Ben böyle bir şey görünüyor veri kümesi var:

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

Her hayvan kimliğinden önce sıfır eklenmesini istiyorum:

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

Ve ilgi uğruna, hayvan kimliğinden önce iki veya üç sıfır eklemem gerekirse ne olur?


6
Hayvan kimlikleri önce yapmanız gereken n sıfırlar eklemek istediğinizi varsayalımdata$anim = paste(rep(0, n), data$anim, sep = "")
Ramnath

2
"Sıfırlar eklemek" istediğinizi söylediğinizde, muhtemelen verinin içine sıfır dolgusu eklemek için tamsayı sütunlarınızı dize / kategoriye dönüştürmek istemezsiniz, bunları tamsayı olarak tutmak ve yalnızca önde gelen sıfırları yazdırmak istersiniz çıktı oluştururken .
smci

Yanıtlar:


555

Kısa sürüm: formatCveya kullanın sprintf.


Daha uzun versiyon:

Sayıları biçimlendirmek için önde gelen sıfır eklenmesi de dahil olmak üzere çeşitli işlevler vardır. Hangisinin en iyisi, diğer biçimlendirmeyi yapmak istediğinize bağlıdır.

Sorudaki örnek oldukça kolaydır, çünkü tüm değerler başlamak için aynı sayıda basamağa sahiptir, bu yüzden 10 genişlik 8 güçlerini yapmak için daha zor bir örnek deneyelim.

anim <- 25499:25504
x <- 10 ^ (0:5)

paste(ve varyantı paste0) genellikle karşılaştığınız ilk dize düzenleme işlevleridir. Sayıları manipüle etmek için gerçekten tasarlanmamıştır, ancak bunun için kullanılabilirler. Her zaman tek bir sıfıra başlamamız gereken basit durumda paste0en iyi çözümdür.

paste0("0", anim)
## [1] "025499" "025500" "025501" "025502" "025503" "025504"

Sayılarda değişken sayıda basamak olduğu durumda, kaç tane sıfırın başlayacağını manuel olarak hesaplamanız gerekir, bu da sadece morbid meraktan yapmanız gereken kadar korkunçtur.


str_paddan stringreser benzer üzere pastesize ped şeyler istediğini daha açık hale.

library(stringr)
str_pad(anim, 6, pad = "0")
## [1] "025499" "025500" "025501" "025502" "025503" "025504"

Yine, gerçekten sayılarla kullanım için tasarlanmamıştır, bu yüzden zor durum biraz düşünmeyi gerektirir. Sadece "genişliği sıfır olan ped 8" diyebilmeliyiz, ancak şu çıktıya bakın:

str_pad(x, 8, pad = "0")
## [1] "00000001" "00000010" "00000100" "00001000" "00010000" "0001e+05"

Bilimsel ceza seçeneğini , sayıların her zaman sabit gösterim (bilimsel gösterim yerine) kullanılarak biçimlendirileceği şekilde ayarlamanız gerekir .

library(withr)
with_options(
  c(scipen = 999), 
  str_pad(x, 8, pad = "0")
)
## [1] "00000001" "00000010" "00000100" "00001000" "00010000" "00100000"

stri_padiçinde stringiaynen gibi eserleri str_padarasından stringr.


formatCC fonksiyonuna bir arayüzdür printf. Bunu kullanmak, altta yatan fonksiyonun arcana bilgisi gerektirir (bağlantıya bakınız). Bu durumda, önemli noktalardır width, argüman formatolmaktan "d""tamsayı" ve a için"0" flag prepending sıfır için.

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"

Bu benim en sevdiğim çözümdür, çünkü genişliği değiştirmekle uğraşmak kolaydır ve işlev diğer biçimlendirme değişiklikleri yapmak için yeterince güçlüdür.


sprintfaynı ismin C fonksiyonuna bir arayüzdür; gibi formatCama farklı bir sözdizimi ile.

sprintf("%06d", anim)
## [1] "025499" "025500" "025501" "025502" "025503" "025504"
sprintf("%08d", x)
## [1] "00000001" "00000010" "00000100" "00001000" "00010000" "00100000"

Başlıca avantajı, sprintfbiçimlendirilmiş sayıları daha uzun metin bitlerine gömebilmenizdir.

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." 

Ayrıca bkz . Goodside cevabı .


Tamlık için, zaman zaman yararlı olan, ancak sıfırları önleme yöntemi olmayan diğer biçimlendirme işlevlerinden bahsetmeye değer.

format, sayılar için bir yöntemle her türlü nesneyi biçimlendirmek için kullanılan genel bir işlevdir. Biraz benzer formatC, ancak başka bir arayüzle çalışıyor.

prettyNumçoğunlukla manuel eksen onay etiketleri oluşturmak için başka bir biçimlendirme işlevidir. Geniş sayı aralıkları için özellikle iyi çalışır.

scalesPaket gibi çeşitli işlevlere sahiptir percent, date_formatve dollaruzman biçim türleri için.


3
büyük yardım için çok teşekkürler. Animasyonuma önde gelen sıfırlar eklemek için formatC'yi kullandım ve iyi çalıştı.
baz

2
formatC (sayı veya vektör, genişlik = 6, format = "d", bayrak = "0") iyi çalıştı (R sürüm 3.0.2 (2013-09-25)). Teşekkürler.
Mohamad Fakih

1
formatC () yöntemini yukarıda açıklanan şekilde kullanmak benim için çalışmadı. Sıfır yerine boşluk ekledi. Ben yanlış bir şey mi yaptım? R sürüm 3.1.1 kullanıyorum.
user1816679 15:14

2
@ user1816679 Unuttuğun gibi geliyor flag = "0".
Richie Cotton

1
?sprintfYardım sayfasının Ayrıntılar bölümü bunu açıklar. "mn: Alan genişliği (m) ve kesinlik (n) olduğunu belirten, nokta ile ayrılmış iki sayı."
Richie Cotton

215

Kaç basamaklı olduğuna bakılmaksızın çalışan genel bir çözüm data$animiçin sprintfişlevi kullanın . Şöyle çalışır:

sprintf("%04d", 1)
# [1] "0001"
sprintf("%04d", 104)
# [1] "0104"
sprintf("%010d", 104)
# [1] "0000000104"

Sizin durumunuzda, muhtemelen: data$anim <- sprintf("%06d", data$anim)


14
sprintfSayıyı dizeye (karakter) dönüştüren unutmayın .
aL3xa

Cevap için teşekkürler. 14 basamaklı bir 13 basamaklı sayı yapmak istiyorum (baştaki sıfırı ekleyerek). Bu işlev bu durumda işe yaramıyor gibi görünüyor. Bana bir hata veriyor: sprintf hatası ("% 020d", 4000100000104): geçersiz biçim '% 020d'; sayısal nesneler için% f,% e,% g veya% a biçimini kullanın. Herhangi bir öneri?
Rotail

Deneyin: sprintf ("% 014.0f", 4000100000104)
Stewart Macdonald

sprintf R 3.4.1
Frank FYC

Evet öyle. 1.5.0 sürümünden bu yana değişmedi.
dash2

33

@ Goodside's repsonse sitesinde genişleyen:

Bazı durumlarda, bir dizeyi sıfırlarla doldurmak isteyebilirsiniz (örn. Fips kodları veya diğer sayısal benzeri faktörler). OSX / Linux'ta:

> sprintf("%05s", "104")
[1] "00104"

Ancak , burada tartışılan sprintf()işletim sisteminin C sprintf()komutunu çağırdığı için , Windows 7'de farklı bir sonuç elde edersiniz:

> sprintf("%05s", "104")
[1] "  104"

Yani Windows makinelerinde geçici çözüm:

> sprintf("%05d", as.numeric("104"))
[1] "00104"

1
Hangi nedenle olursa olsun, bu çözüm artık Linux'ta benim için çalışmıyor. @ kdauria's str_padartık benim gitmem.
metasequoia

25

str_padgelen stringrpaketin bir alternatiftir.

anim = 25499:25504
str_pad(anim, width=6, pad="0")

4
str_padBeklenmedik sonuçlara yol açabileceğinden çok dikkatli olun . i.num = 600000; str_pad(i.num, width = 7, pad = "0") "066000" değil "006e + 05" verecek
Pankil Shah

2

İşte genelleştirilebilir bir temel R işlevi:

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)

Seviyorum sprintfama gibi uyarılar ile geliyor:

ancak asıl uygulama C99 standardını takip edecek ve ince detaylar (özellikle kullanıcı hatası altındaki davranış) platforma bağlı olabilir


1

İşte CUSIP'ler gibi dizelere 0'lara yol eklemek için başka bir alternatif bazen bir sayı gibi görünebilen ve Excel gibi birçok uygulamanın bozup kaldıracağı veya bunları bilimsel gösterime dönüştürebileceği .

@Metasequoia tarafından verilen cevabı denediğimde, geri dönen vektör 0s değil, önde gelen boşluklara sahipti . Bu, @ user1816679 tarafından belirtilen sorunla aynıydı - ve etrafındaki tırnak işaretlerinin kaldırılması 0ya da 'dan değiştirilmesi' %dde %sbir fark yaratmadı. FYI, bir Ubuntu Sunucusu üzerinde çalışan RStudio Sunucusu kullanıyorum. Bu iki aşamalı çözüm benim için çalıştı:

gsub(pattern = " ", replacement = "0", x = sprintf(fmt = "%09s", ids[,CUSIP]))

%>%Boru işlevini magrittrpaketten kullanarak şöyle görünebilir:

sprintf(fmt = "%09s", ids[,CUSIP]) %>% gsub(pattern = " ", replacement = "0", x = .)

Tek işlevli bir çözümü tercih ederim, ama işe yarıyor.



0

Sayı dizesinin tutarlı olmasını istediğiniz diğer durumlar için bir işlev yaptım.

Birisi bunu faydalı bulabilir:

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)

Biçimlendirme için üzgünüm.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.