จะเพิ่มศูนย์นำหน้าได้อย่างไร


352

ฉันมีชุดข้อมูลซึ่งมีลักษณะดังนี้:

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

ฉันต้องการเพิ่มศูนย์ก่อนหน้า id สัตว์แต่ละตัว:

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

และเพื่อความสนใจจะเกิดอะไรขึ้นถ้าฉันต้องเพิ่มศูนย์สองหรือสามเลขหน้าสัตว์ id?


6
สมมติว่าคุณต้องการที่จะเพิ่ม n ศูนย์ก่อนรหัสสัตว์คุณเพียงแค่ต้องทำdata$anim = paste(rep(0, n), data$anim, sep = "")
Ramnath

2
เมื่อคุณบอกว่าคุณต้องการ "เพิ่มเลขศูนย์" คุณคงไม่ต้องการแปลงคอลัมน์จำนวนเต็มเป็นสตริง / หมวดหมู่เพื่อเพิ่มศูนย์เติมภายในข้อมูลเองคุณต้องการเก็บจำนวนเต็มและพิมพ์เลขศูนย์นำหน้าเท่านั้น เมื่อแสดงเอาท์พุท
smci

คำตอบ:


555

รุ่นสั้น: การใช้งานหรือformatCsprintf


รุ่นที่ยาวกว่า:

มีหลายฟังก์ชั่นสำหรับจัดรูปแบบตัวเลขรวมถึงการเพิ่มเลขศูนย์นำหน้า รูปแบบใดดีที่สุดขึ้นอยู่กับการจัดรูปแบบอื่นที่คุณต้องการทำ

ตัวอย่างจากคำถามนั้นค่อนข้างง่ายเนื่องจากค่าทั้งหมดมีจำนวนหลักเท่ากันเริ่มต้นดังนั้นลองทำตัวอย่างที่ยากขึ้นในการสร้างพลังของความกว้าง 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"

อีกครั้งมันไม่ได้ออกแบบมาเพื่อใช้กับตัวเลขดังนั้นกรณีที่ยากกว่านั้นต้องใช้ความคิดเล็กน้อย เราควรจะสามารถพูดว่า "แผ่นที่มีเลขศูนย์ถึงความกว้าง 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_padstringr


formatCprintfเป็นอินเตอร์เฟซฟังก์ชั่นซี การใช้มันต้องการความรู้เกี่ยวกับอาร์คานาของฟังก์ชั่นพื้นฐานนั้น (ดูลิงค์) ในกรณีนี้ประเด็นสำคัญคือการwidthโต้แย้งformatเป็น"d"สำหรับ "จำนวนเต็ม" และ"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ประเภทรูปแบบผู้เชี่ยวชาญ


3
ขอบคุณมากสำหรับความช่วยเหลือที่ดี ฉันใช้ formatC เพื่อเพิ่มศูนย์นำหน้าให้กับอนิเมชั่นของฉันและมันทำงานได้ดี
baz

2
formatC (ตัวเลขหรือเวกเตอร์, ความกว้าง = 6, format = "d", flag = "0") ทำงานได้ดี (รุ่น R 3.0.2 (2013-09-25)) ขอบคุณ
Mohamad Fakih

1
ใช้ formatC () ตามวิธีที่อธิบายไว้ข้างต้นไม่ได้ผลสำหรับฉัน มันเพิ่มช่องว่างแทนศูนย์ ฉันทำอะไรผิดหรือเปล่า? ฉันใช้ R เวอร์ชั่น 3.1.1
user1816679

2
@ เสียง user1816679 flag = "0"เหมือนคุณลืม
Richie Cotton

1
ส่วนรายละเอียดของ?sprintfหน้าช่วยเหลืออธิบายสิ่งนี้ "mn: ตัวเลขสองตัวคั่นด้วยจุดหนึ่งแสดงถึงความกว้างของสนาม (m) และความแม่นยำ (n)"
Richie Cotton

215

สำหรับโซลูชันทั่วไปที่ใช้งานได้โดยไม่คำนึงว่าจะมีตัวเลขกี่หลักdata$animให้ใช้sprintfฟังก์ชัน มันทำงานได้เช่นนี้:

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

ในกรณีของคุณคุณอาจต้องการ: data$anim <- sprintf("%06d", data$anim)


14
โปรดทราบว่าsprintfแปลงตัวเลขเป็นสตริง (อักขระ)
aL3xa

ขอบคุณสำหรับคำตอบ. ฉันต้องการทำให้ตัวเลข 13 หลักเป็น 14 หลัก (เพิ่มศูนย์นำหน้า) ฟังก์ชั่นนี้ใช้ไม่ได้กับกรณีนี้ มันทำให้ฉันมีข้อผิดพลาด: ข้อผิดพลาดใน sprintf ("% 020d", 4000100000104): รูปแบบที่ไม่ถูกต้อง '% 020d'; ใช้รูปแบบ% f,% e,% g หรือ% a สำหรับวัตถุที่เป็นตัวเลข ข้อเสนอแนะใด ๆ
Rotail

ลอง: sprintf ("% 014.0f", 4000100000104)
Stewart Macdonald

sprintf ไม่สามารถใช้ได้สำหรับ R 3.4.1
Frank FYC

ใช่แล้ว. มันไม่เปลี่ยนแปลงตั้งแต่รุ่น 1.5.0
dash2

33

การขยายคำตอบของ @ goodside:

ในบางกรณีคุณอาจต้องการวางสตริงด้วยค่าศูนย์ (เช่นรหัส fips หรือปัจจัยอื่น ๆ ที่เป็นตัวเลข) ใน OSX / Linux:

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

แต่เนื่องจากการsprintf()เรียกsprintf()คำสั่งC ของระบบปฏิบัติการซึ่งกล่าวถึงที่นี่ใน Windows 7 คุณได้รับผลลัพธ์ที่แตกต่าง:

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

ดังนั้นในเครื่อง Windows การทำงานคือ:

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

1
ไม่ว่าจะด้วยเหตุผลใดก็ตามโซลูชันนี้ใช้งานไม่ได้บน Linux @ kdauria str_padตอนนี้ฉันไปแล้ว
metasequoia

25

str_padจากstringrแพคเกจเป็นทางเลือก

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

4
ระมัดระวังด้วยstr_padเพราะอาจนำไปสู่ผลลัพธ์ที่ไม่คาดคิด i.num = 600000; str_pad(i.num, width = 7, pad = "0") จะให้ "006e + 05" และไม่ใช่ "0600000"
Pankil Shah

2

นี่คือฟังก์ชั่นพื้นฐาน generalizable:

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แต่มันมาพร้อมกับ caveats เช่น:

อย่างไรก็ตามการใช้งานจริงจะเป็นไปตามมาตรฐาน C99 และรายละเอียดที่ดี (โดยเฉพาะอย่างยิ่งพฤติกรรมภายใต้ข้อผิดพลาดของผู้ใช้) อาจขึ้นอยู่กับแพลตฟอร์ม


1

นี่คืออีกทางเลือกหนึ่งสำหรับการเพิ่มที่นำไปสู่ ​​0s ไปยังสตริงเช่นCUSIPsซึ่งบางครั้งอาจมีลักษณะเป็นตัวเลขและแอปพลิเคชันจำนวนมากเช่น Excel จะเสียหายและลบ 0s นำหรือแปลงเป็นสัญลักษณ์ทางวิทยาศาสตร์

เมื่อฉันลองคำตอบจาก @metasequoia เวกเตอร์ที่ส่งคืนมามีช่องว่างนำหน้าไม่ใช่0s นี่เป็นปัญหาเดียวกันที่กล่าวถึงโดย @ user1816679 - และการลบเครื่องหมายคำพูดรอบ ๆ0หรือเปลี่ยนจาก%dเป็น%sไม่ทำให้เกิดความแตกต่าง มาก่อน, ฉันใช้ RStudio Server ที่ทำงานบน Ubuntu Server โซลูชันสองขั้นตอนเล็ก ๆ นี้ใช้ได้สำหรับฉัน:

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

ใช้%>%ฟังก์ชั่นไปป์จากmagrittrแพ็คเกจมันอาจมีลักษณะเช่นนี้

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

ฉันต้องการโซลูชันแบบฟังก์ชั่นเดียว แต่ใช้งานได้



0

สำหรับกรณีอื่น ๆ ที่คุณต้องการให้สตริงตัวเลขสอดคล้องกันฉันสร้างฟังก์ชันขึ้นมา

บางคนอาจพบว่ามีประโยชน์:

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)

ขออภัยเกี่ยวกับการจัดรูปแบบ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.