Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Don't drop zero in unquoted string as argument

Tags:

r

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 <- 
function(...){ 
    substitute(...())
}

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 <- 
function(...){ 
    x <- match.call(expand.dots = FALSE)
    as.character(x[[2]])
}

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

like image 857
Tyler Rinker Avatar asked Oct 24 '12 16:10

Tyler Rinker


2 Answers

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 <- 
  function(...){
    savehistory(file <- tempfile())
    hist <- readLines(file)
    args <- hist[length(hist)]
    args <- unlist(regmatches(args,gregexpr("(?<=fun\\().*(?=\\))",args,perl=TRUE)))
    args <- unlist(strsplit(args,split=","))
    as.character(args)
  }

Example:

> 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.

like image 141
Sacha Epskamp Avatar answered Nov 13 '22 14:11

Sacha Epskamp


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:

 foo<-function(){
 + 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: '

like image 3
Carl Witthoft Avatar answered Nov 13 '22 15:11

Carl Witthoft