11.4 Formatted Printing
Quite often when we are printing out to the console we want each line to follow some uniform format. This can be accomplished with the sprintf()
function.28 Lets begin with an example:
<- "Mary"
first <- "Poppins"
last sprintf(fmt = "%10s%20s", first, last)
## [1] " Mary Poppins"
sprintf()
builds a string from the strings first
and last
that were passed to it. The fmt
parameter is a string that encodes the format of the result. In this example, the command comes down to:
- create a string of width 10, consisting of five spaces followed by the five characters of “Mary”
- create a string of width 20, consisting of 13 spaces followed by the seven characters of “Poppins”
- The preceding two strings are called fields. We then join the above the fields, with nothing between them.
Here is the result, cat
ed out:
sprintf(fmt = "%10s%20s", first, last) %>%
cat()
## Mary Poppins
The “s” in the the fmt
argument is called a conversion character. It tells sprintf()
to expect a string. Each percent sign indicates the beginning of a new field. For each field, the desired field-width should appear between the percent-sign and the conversion character for the field.
In the text above, the names are right-justified, meaning that they appear at the end of their respective fields. If you want a field to be left-justified, insert a hyphen anywhere between the percent sign and the conversion character, like so:
# left-justify both fields:
sprintf(fmt = "%-10s%-20s", first, last) %>% cat()
## Mary Poppins
Other common conversion characters are:
d
: an integerf
: a decimal number (default is 6 digits precision)g
: a decimal number where the default precision is determined by the number of significant figures in the given number
Here is another example:
sprintf(fmt = "%-10s%-10d%-10f", "Mary", 1955, 3.2) %>% cat()
## Mary 1955 3.200000
The following example is the same as above, except that we retain only the significant figures in the 3.2:
sprintf(fmt = "%-10s%-10d%-10g", "Mary", 1955, 3.2) %>% cat()
## Mary 1955 3.2
When you are creating a field for a decimal number, you can specify both the total field-width and the precision together if you separate them with a .
. Thus, if you want the number 234.5647 to appear right-justified in a field of width 10, showing only the first three decimal places, then try:
sprintf(fmt = "%-10s%-10d%-10.3f", "Mary", 1955, 234.5647) %>%
cat()
## Mary 1955 234.565
sprintf()
comes in handy when you want your output to appear in nicely-aligned, tabular fashion. Consider this example:
# information for three people:
<- c("Donald", "Gina", "Rohini")
firstName <- c("Duck", "Gentorious", "Lancaster")
lastName <- c(17, 19, 20)
age <- c(3.7, 3.9, 3.823)
gpa for (i in 1:3) {
sprintf("%-15s%-20s%-5d%-5.2f\n",
%>%
firstName[i], lastName[i], age[i], gpa[i]) cat()
}
## Donald Duck 17 3.70
## Gina Gentorious 19 3.90
## Rohini Lancaster 20 3.82
Note the use of “\n” in the fmt
argument to ensure that the output appears on separate lines.
You could take advantage of vectorization to avoid the loop:
sprintf("%-15s%-20s%5-d%-5.2f\n",
%>%
firstName, lastName, age, gpa) cat()
## Donald Duck 17 3.70
## Gina Gentorious 19 3.90
## Rohini Lancaster 20 3.82
Well, that’s not quite right: the second and third lines begin with a space. This happens because cat()
separates its input with a space by default. You can prevent this, however, with the sep
parameter of cat()
:
sprintf("%-15s%-20s%-5d%-5.2f\n",
%>%
firstName, lastName, age, gpa) cat(sep = "")
## Donald Duck 17 3.70
## Gina Gentorious 19 3.90
## Rohini Lancaster 20 3.82
You can think of
sprintf
as short for: “formatted printing in S.” S was the forerunner to the R language.↩︎