7

Consider this code:

sample(1:20, 1)

If the result happens to be less than or equal to 10, can I get R to print out the number as a word. For example, if the result of sample(1:20, 1) is 2, can I program R to print the result as two, if the result of sample(1:20, 1) is 10, can I program R to print the result as ten, if the result of sample(1:20, 1) is 13, can I program R to print the result as 13, and so on.

I am using knitrto convert R code to latex for my thesis. My rule is any number less than or equal to 10 should be printed as word.

luciano
  • 13,158
  • 36
  • 90
  • 130

3 Answers3

13

You can use the english package to transform numbers into English words:

set.seed(1)
s <- sample(1:20, 10)
# [1]  6  8 11 16  4 14 15  9 19  1

library(english)
ifelse(s > 10, s, as.character(english(s)))
# [1] "six"   "eight" "11"    "16"    "four"  "14"    "15"    "nine"  "19"    "one"
Sven Hohenstein
  • 80,497
  • 17
  • 145
  • 168
  • This general approach is perfect. There are also a few alternatives to the `english` package available (`qdap` and `xfun` are two). Here are a couple examples of functions similar to `english()`: https://stackoverflow.com/a/46652277/5373794 – bschneidr Nov 08 '18 at 15:24
8

Here’s essentially the same as Mark’s answer, but quite a bit more concise:

numbers = c('zero', 'one', 'two', 'three', 'four', 'five',
            'six', 'seven', 'eight', 'nine', 'ten')
readable = function (x) ifelse(x < 11, numbers[x + 1], x)
> readable(sample(1:20, 10))
 [1] "20"    "12"    "13"    "seven" "ten"   "11"    "17"    "eight" "16"    "18"

Although if you’re using knitr with LaTeX, this is arguably a task for LaTeX, not for R: R provides the raw data, LaTeX is in charge of formatting. I would probably just tell knitr to issue numbers wrapped inside a macro – \readable{42} – and then do the conversion with this macro (untested, and requires the package siunitx):

\newcommand*\readable[1]{%
  \ifcase#1 zero\or one\or two\or three\or four\or five\or
    six\or seven\or eight\or nine\or ten\else\num{#1}}
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
2

This is not elegant, but I think it will do what you want.

set.seed(1234)

x <- sample(1:20, 1)

my.data <- read.table(text='
  x    y
  0    zero
  1    one
  2    two
  3    three
  4    four
  5    five
  6    six
  7    seven
  8    eight
  9    nine
  10   ten
', header = TRUE)

if(x > 10) {y = x} else {y = my.data$y[x == my.data$x]}

data.frame(x, y)

  x     y
1 3 three

Here is a way to convert many numbers at once:

set.seed(1234)

x <- sample(1:20, 10)
x <- as.data.frame(x)

my.data <- read.table(text='
  x    y
  0    zero
  1    one
  2    two
  3    three
  4    four
  5    five
  6    six
  7    seven
  8    eight
  9    nine
  10   ten
', header = TRUE, stringsAsFactors = FALSE)

y <- apply(x, 1, function(i) if(i > 10) {y = i} else {y = my.data$y[i == my.data$x]})

data.frame(x, y)

    x     y
1   3 three
2  12    12
3  11    11
4  18    18
5  14    14
6  10   ten
7   1   one
8   4  four
9   8 eight
10  6   six
Mark Miller
  • 12,483
  • 23
  • 78
  • 132