2012-10-24 3 views
6

Próbuję wykonać funkcję dla pakietu, który umożliwia użytkownikowi odczyt w danych bez cudzysłowów. Działa niemal zgodnie z oczekiwaniami, z wyjątkiem tego, że funkcja zamienia 3,30 na 3.3, nawet jeśli ostateczne wyjście jest charakterystyczne. W jaki sposób mogę uzyskać funkcję odczytu w elementach będących liczbami, ale nie po to, aby znikały końcowe zera. Obraz wielka idea jest:Nie upuszczaj zera w niecytowanym łańcuchu jako argument

  1. funkcja, która odczytuje elementów bez użycia cudzysłowu
  2. funkcja nie będzie wyrzucić co R uważa nieistotnych zer
  3. chociaż elementy mogą wyglądać numeryczny chcę, żeby być wyprowadzane jako znak Elements

Oto dwie próby i to, co na zewnątrz put (jedna próba z substitute(...()) a drugi z 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" 

Z cudzysłowu wyprowadza co chcę, ale to pokonuje cel nie mający zapewnić cudzysłów:

fun('3.30', '5.05') 

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

PS Jeśli ktoś ma lepszy tytuł dla tego wątku czuje swobodnie edytować

Odpowiedz

5

Dobrze jest jeden sposób mogę myśleć, ale to nie jest całkiem całkiem i może nie być stabilny. R zapisuje również historię wprowadzonych połączeń. Które mogą być wykorzystywane w celu uzyskania dokładnego wkład:

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) 
    } 

Przykład:

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

Nie jestem pewien, jak to będzie stabilny, nie będzie prawdopodobnie kilkanaście przypadków będzie przerwa. Ponadto zakłada się, że funkcja nazywa się fun.

+0

Bingo - to wszystko, o czym mógłbym pomyśleć, i to się zepsuje, jeśli wywołanie funkcji "fun()" rozciąga się na dwie lub więcej linii, lub jeśli jeden z argumentów znaków zawiera przecinek, lub jeśli fun() 'jest wywoływana przez inną funkcję lub ... Wciąż bardzo miła odpowiedź! –

+0

Imponująca Dziękuję +1 –

2

Niestety nie jest to możliwe. Podobnie jak w większości języków, R traktuje tak samo 3.3 i 3.30 (innymi słowy, liczba cyfr znaczących nie jest zapisywana).

> 3.30 
[1] 3.3 

> 3.30 == 3.3 
[1] TRUE 

> deparse(3.30) 
[1] "3.3" 

Jeśli wszystkie wejścia mają taką samą liczbę cyfr, można użyć format aby uzyskać prawo Wynik

> format(3.3, nsmall=2) 
[1] "3.30" 
3

Mogę być nieco gęsty dzisiaj, ale readlines('enter something') z następującym po nim wpisem "3,30" (bez cudzysłowów) daje zwróconą wartość znaku "3,30".

Tak więc albo wypełnij swoją funkcję rozmowami readlines lub wykop źródła do readlines i zmodyfikuj je zgodnie ze swoimi potrzebami.

Choć muszę powiedzieć, łatwiej byłoby, gdyby użytkownik po prostu wpisze wszystko do pliku i, jeśli to konieczne, odczyta plik z read.table lub scan i określi typ wejścia jako "znak".

W odpowiedzi na komentarz Tylera:

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

Przypuszczalnie można podzielić ciąg takiego w dowolny sposób chcesz :-) dostać poszczególne ciągi numeryczne.(Użytkownik wpisuje rzeczy następujące po znaku zachęty "wprowadź dane:"

+0

Dzięki Carl.Ale to może być w środku Funkcja? Jestem osobą, czytania i nie wiele osób w mojej dziedzinie są wiedzę R (to, dla kogo ten pakiet jest przeznaczony) .To musi być bardzo łatwe w użyciu.Nie dodatkowe połączenia z niczym '' readlines'. –

+0

@ TylerRinker jest moją aktualizacją pomocną? –

+0

Tak, robi +1 –

Powiązane problemy