Take the 2-minute tour ×

I'm attempting to make a function for a package that allows the user to read in data without quotation marks. It works almost as expected except the function turns 3.30 into 3.3 even though the final output is character. How can I get my function to read in elements that are numbers but not to drop trailing zeros. The big picture idea is:

  1. function that reads elements without using quotation marks
  2. function will not discard what R considers non significant zeros
  3. though the elements may look numeric I want them to be outputted as character elements

Here are two attempts and what they out put (one attempt with substitute(...()) and the other with match.call(expand.dots = FALSE):

#attempt #1 
fun <- 

fun(3.30, 5.05)

#dropped zero on 3:30 (not what I want)
> fun(3.30, 5.05)
[1] "3.3"  "5.05"

#attempt #2 
fun <- 
    x <- match.call(expand.dots = FALSE)

fun(3.30, 5.05)

#again dropped zero on 3:30 (not what I want)    
> fun(3.30, 5.05)
[1] "3.3"  "5.05"

With quotation marks it outputs what I want but this defeats the purpose of not having to provide quotation marks:

fun('3.30', '5.05')

> fun('3.30', '5.05')
[1] "3.30" "5.05"

PS if someone has a better title for this thread feel free to edit

share|improve this question
add comment

3 Answers

up vote 5 down vote accepted

Well there is one way I could think of but it isn't quite pretty and might not be stable. R also saves history of the entered calls. That could be used to obtain the exact input:

fun <- 
    savehistory(file <- tempfile())
    hist <- readLines(file)
    args <- hist[length(hist)]
    args <- unlist(regmatches(args,gregexpr("(?<=fun\\().*(?=\\))",args,perl=TRUE)))
    args <- unlist(strsplit(args,split=","))


> fun(2.20,3.14,pi,0.000000)
[1] "2.20"     "3.14"     "pi"       "0.000000"

I am not sure how stable this would be, there will probably be a dozen cases it will break. Also, this assumes the function is named fun.

share|improve this answer
Bingo. This is all I could think of too, and it'll break if the call to fun() extends over two or more lines, or if one of the character arguments contains a comma, or if fun() is called by another function or ... Still, very nice answer! –  Josh O'Brien Oct 24 '12 at 18:24
Impressive. Thank you +1 –  Tyler Rinker Oct 24 '12 at 18:51
add comment

I may be a bit dense today, but readlines('enter something') followed by typing "3.30" (whithout the quotes) produces the returned character value "3.30" .

So either fill your function with readlines calls or maybe dig up the source to readlines and modify it to fit your needs.

Though I have to say it would seem a lot easier to have the user just type everything into a file and, if desired, read the file with read.table or scan and specify input type as "character".

In answer to Tyler's comment:

 + readline('enter data: ')->foostuff
 + return(foostuff)
 + }
 > foo()
 enter data: 4.30 56 hello world
 [1] "4.30 56 hello world"

Presumably you can split a string like that up any way you want :-) to get the individual number strings. (The user types the stuff following the prompt 'enter data: '

share|improve this answer
Thanks Carl. But can that be fit inside of a function? I'm a literacy person and not many people in my field are R knowledgeable (that's who this package is for). This thing has to be very easy to use. No extra calls to anything like readlines. –  Tyler Rinker Oct 24 '12 at 19:53
@TylerRinker is my update helpful? –  Carl Witthoft Oct 24 '12 at 19:59
Yes it does. +1 –  Tyler Rinker Oct 24 '12 at 22:17
add comment

Unfortunately, this isn't possible. Like most languages, R treats 3.3 and 3.30 as the same (in other words, the number of significant digits is not stored).

> 3.30
[1] 3.3

> 3.30 == 3.3
[1] TRUE

> deparse(3.30)
[1] "3.3"

If all your inputs have the same number of digits, you can use format to get the right result

> format(3.3, nsmall=2)
[1] "3.30"
share|improve this answer
add comment

Your Answer


