How to only show two decimal points without rounding - r

For a value like 0.999942062, I would like to show this value as 0.99 without rounding to 1. For that, I tried the following functions:
x <- 0.999942062
round(x, 2)
formatC(x, 2)
sprintf(x, fmt = '%#.2f')
They all result in 1. Do you know how to print it like 0.99?

You could use substr() converted into "character" beforehand.
substr(as.character(0.999942062), 1, 4)
# [1] "0.99"

Use trunc(x * 10^n) / 10^n as you want to simply truncate your number (effectively rounding it towards 0)
also floor(x * 10^n) / 10^n would archieve the same for positive numbers
Edit:
changed floor and trunc usage as I had memorized them wrongly as #Sotos and #Roland pointed out

x = c(0.999942062, 20)
gsub("(.*)(\\.)(.{2}).*", "\\1\\2\\3", x)
#[1] "0.99" "20"

if your number could have varying number of digits to the left of the decimal point, you'll want to use regexpr inside of substr after converting to character to locate the decimal point and then add two digits to the end. Like so:
substr(as.character(10.999462), 1, regexpr("\\.", as.character(10.999462)) + 2)

Related

Getting last two digits of Sequence Date in R

I have sequence date:
names<-format(seq.Date(as.Date("2012-11-01"),as.Date("2012-12-01"),
by = 'months'),format = "%Y%m")
How can I get the last two digit, like the result for last two digits of names[1] is 11?
Using the stringr package you can just put
stringr::str_sub(string = names, start = -2, end = -1)
You could use substr():
names = substr(names, nchar(names)-1, nchar(names))
The result is:
[1] "11" "12"
Or as integer:
names = as.integer(substr(names, nchar(names)-1, nchar(names))
Result:
[1] 11 12
There can be tenths of ways. The simpliest I could invent was to find the remainder of intiger division:
as.integer(names) %% 100
that returns:
[1] 11 12
Technically these are integers. If you stricktly require characters apply as.character() to the result to cast the type.

R-- Add leading zero to string, with no fixed string format

I have a column as below.
9453, 55489, 4588, 18893, 4457, 2339, 45489HQ, 7833HQ
I would like to add leading zero if the number is less than 5 digits. However, some numbers have "HQ" in the end, some don't.(I did check other posts, they dont have similar problem in the "HQ" part)
so the finally desired output should be:
09453, 55489, 04588, 18893, 04457, 02339, 45489HQ, 07833HQ
any idea how to do this? Thank you so much for reading my post!
A one-liner using regular expressions:
my_strings <- c("9453", "55489", "4588",
"18893", "4457", "2339", "45489HQ", "7833HQ")
gsub("^([0-9]{1,4})(HQ|$)", "0\\1\\2",my_strings)
[1] "09453" "55489" "04588" "18893"
"04457" "02339" "45489HQ" "07833HQ"
Explanation:
^ start of string
[0-9]{1,4} one to four numbers in a row
(HQ|$) the string "HQ" or the end of the string
Parentheses represent capture groups in order. So 0\\1\\2 means 0 followed by the first capture group [0-9]{1,4} and the second capture group HQ|$.
Of course if there is 5 numbers, then the regex isn't matched, so it doesn't change.
I was going to use the sprintf approach, but found the the stringr package provides a very easy solution.
library(stringr)
x <- c("9453", "55489", "4588", "18893", "4457", "2339", "45489HQ", "7833HQ")
[1] "9453" "55489" "4588" "18893" "4457" "2339" "45489HQ" "7833HQ"
This can be converted with one simple stringr::str_pad() function:
stringr::str_pad(x, 5, side="left", pad="0")
[1] "09453" "55489" "04588" "18893" "04457" "02339" "45489HQ" "7833HQ"
If the number needs to be padded even if the total string width is >5, then the number and text need to be separated with regex.
The following will work. It combines regex matching with the very helpful sprintf() function:
sprintf("%05.0f%s", # this encodes the format and recombines the number with padding (%05.0f) with text(%s)
as.numeric(gsub("^(\\d+).*", "\\1", x)), #get the number
gsub("[[:digit:]]+([a-zA-Z]*)$", "\\1", x)) #get just the text at the end
[1] "09453" "55489" "04588" "18893" "04457" "02339" "45489HQ" "07833HQ"
Another attempt, which will also work in cases like "123" or "1HQR":
x <- c("18893","4457","45489HQ","7833HQ","123", "1HQR")
regmatches(x, regexpr("^\\d+", x)) <- sprintf("%05d", as.numeric(sub("\\D+$","",x)))
x
#[1] "18893" "04457" "45489HQ" "07833HQ" "00123" "00001HQR"
This basically finds any numbers at the start of the string (^\\d+) and replaces them with a zero-padded (via sprintf) string that was subset out by removing any non-numeric characters (\\D+$) from the end of the string.
We can use only sprintf() and gsub() by splitting up the parts then putting them back together.
sprintf("%05d%s", as.numeric(gsub("[^0-9]+", "", x)), gsub("[0-9]+", "", x))
# [1] "18893" "04457" "45489HQ" "07833HQ" "00123" "00001HQR"
Using #thelatemail's data:
x <- c("18893", "4457", "45489HQ", "7833HQ", "123", "1HQR")

Extract/Remove portion of an Integer or string with random digits/characters in R

Say I have an integer
x <- as.integer(442009)
or a character string
y <- "a10ba3m1"
How do I eliminate the last two digits/character of integer/string of any length in general ?
substr returns substrings:
substr(x, 1, nchar(x)-2)
# [1] "4420"
substr(y, 1, nchar(y)-2)
# [1] "a10ba3"
If you know that the value is an integer, then you can just divide by 100 and convert back to integer (drop the decimal part). This is probably a little more efficient than converting it to a string then back.
> x <- as.integer(442009)
> floor(x/100)
[1] 4420
If you just want to remove the last 2 characters of a string then substr works.
Or, here is a regular expression that does it as well (less efficiently than substr:
> y <- "a10ba3m1"
> sub("..$", "", y)
[1] "a10ba3"
If you want to remove the last 2 digits (not any character) from a string and the last 2 digits are not guaranteed to be in the last 2 positions, then here is a regular expression that works:
> sub("[0-9]?([^0-9]*)[0-9]([^0-9]*)$", "\\1\\2", y)
[1] "a10bam"
If you want to remove up to 2 digits that appear at the very end (but not if any non digits come after them) then use this regular expression:
> sub("[0-9]{1,2}$", "", y)
[1] "a10ba3m"

how do you format numbers in vector without having extra spaces and quotes around the numbers

I have a vector like this:
dput(yy)
c(97.1433841613379, 1102.1208262592, 32.5418522860492, 217.694780086999,
1306.31759309228, 202.18335752298, 22.8301149425287)
I need to only keep 2 decimal points and I am doing this to get rid of additional decimal points:
yy<-format(yy, digits=1)
When I do dput(yy), I get additional spaces in front of the my values as this:
dput(yy)
c(" 97.14", "1102.12", " 32.54", " 217.69", "1306.32", " 202.18",
" 22.83")
Is there an easy way to format the numbers without inserting extra space and quotes around the numbers?
You could use ?sprintf (it use the same syntax like sprintf in C):
x <- c(97.1433841613379, 1102.1208262592, 32.5418522860492, 217.694780086999, 1306.31759309228, 202.18335752298, 22.8301149425287)
sprintf("%.2f", x)
# [1] "97.14" "1102.12" "32.54" "217.69" "1306.32" "202.18" "22.83"
EDIT:
Or do you look for ?round?
round(x, digits=2)
# [1] 97.14 1102.12 32.54 217.69 1306.32 202.18 22.83
If you want to keep everything as numbers then use round(x, 2), however that will change a number like 1.5000002 to 1.5 rather than 1.50 that you could get with format or sprintf.

How to format a number with specified level of precision?

I would like to create a function that returns a vector of numbers a precision reflected by having only n significant figures, but without trailing zeros, and not in scientific notation
e.g, I would like
somenumbers <- c(0.000001234567, 1234567.89)
myformat(x = somenumbers, n = 3)
to return
[1] 0.00000123 1230000
I have been playing with format, formatC, and sprintf, but they don't seem to want to work on each number independently, and they return the numbers as character strings (in quotes).
This is the closest that i have gotten example:
> format(signif(somenumbers,4), scientific=FALSE)
[1] " 0.000001235" "1235000.000000000"
You can use the signif function to round to a given number of significant digits. If you don't want extra trailing 0's then don't "print" the results but do something else with them.
> somenumbers <- c(0.000001234567, 1234567.89)
> options(scipen=5)
> cat(signif(somenumbers,3),'\n')
0.00000123 1230000
>
sprintf seems to do it:
sprintf(c("%1.8f", "%1.0f"), signif(somenumbers, 3))
[1] "0.00000123" "1230000"
how about
myformat <- function(x, n) {
noquote(sapply(a,function(x) format(signif(x,2), scientific=FALSE)))
}

Resources