2012-10-24 22 views
6

Tôi đang cố gắng thực hiện một chức năng cho gói cho phép người dùng đọc dữ liệu mà không có dấu ngoặc kép. Nó hoạt động gần như mong đợi ngoại trừ chức năng biến 3.30 thành 3.3 mặc dù đầu ra cuối cùng là ký tự. Làm thế nào tôi có thể nhận được chức năng của tôi để đọc trong các yếu tố đó là con số nhưng không phải để thả số không dấu. Ý tưởng bức tranh lớn là:Không thả số không trong chuỗi chưa được trích dẫn làm đối số

  1. chức năng mà đọc yếu tố mà không sử dụng dấu ngoặc kép
  2. chức năng sẽ không loại bỏ những gì R coi số không không quan trọng
  3. mặc dù các yếu tố có thể nhìn số tôi muốn họ được outputted như nhân vật yếu tố

Dưới đây là hai nỗ lực và những gì họ đặt ra (một nỗ lực với substitute(...()) và khác với 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" 

Với dấu ngoặc kép nó ra những gì tôi muốn nhưng điều này đánh bại mục đích của việc không phải cung cấp dấu ngoặc kép:

fun('3.30', '5.05') 

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

PS nếu ai đó có một tiêu đề tốt hơn cho chủ đề này cảm thấy tự do để chỉnh sửa

Trả lời

5

Vâng có một cách tôi có thể nghĩ đến, nhưng nó không phải là khá đẹp và có thể không ổn định. R cũng lưu lịch sử của các cuộc gọi đã nhập. Điều đó có thể được sử dụng để có được đầu vào chính xác:

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

Ví dụ:

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

Tôi không chắc chắn như thế nào ổn định này sẽ được, có lẽ sẽ là một chục trường hợp nó sẽ phá vỡ. Ngoài ra, điều này giả định hàm được đặt tên là fun.

+0

Bingo. Đây là tất cả những gì tôi có thể nghĩ đến, và nó sẽ hỏng nếu lệnh gọi 'fun()' kéo dài trên hai hoặc nhiều dòng, hoặc nếu một trong các đối số ký tự chứa dấu phẩy, hoặc nếu 'fun()' được gọi bởi một hàm khác hoặc ... Câu trả lời vẫn rất hay! –

+0

Ấn tượng Cảm ơn bạn +1 –

2

Thật không may, điều này là không thể. Giống như hầu hết các ngôn ngữ, R xử lý 3.3 và 3.30 như nhau (nói cách khác, số lượng chữ số có nghĩa không được lưu trữ).

> 3.30 
[1] 3.3 

> 3.30 == 3.3 
[1] TRUE 

> deparse(3.30) 
[1] "3.3" 

Nếu tất cả các đầu vào của bạn có cùng số chữ số, bạn có thể sử dụng format để có được kết quả đúng

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

Hôm nay tôi có thể hơi dày đặc, nhưng readlines('enter something'), sau đó nhập "3,30" (không có dấu ngoặc kép) sẽ tạo ra giá trị ký tự trả về "3,30".

Vì vậy, hãy điền vào chức năng của bạn với các cuộc gọi readlines hoặc có thể khai thác nguồn tới readlines và sửa đổi nó để phù hợp với nhu cầu của bạn.

Mặc dù tôi phải nói rằng có vẻ dễ dàng hơn khi người dùng chỉ cần nhập mọi thứ vào một tệp và nếu muốn, hãy đọc tệp với read.table hoặc scan và chỉ định loại đầu vào là "ký tự".

Trong câu trả lời cho bình luận của Tyler:

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

Có lẽ bạn có thể chia một chuỗi như thế lên bất kỳ cách nào bạn muốn :-) để có được những chuỗi số cá nhân.(Người dùng nhập nội dung theo lời nhắc 'nhập dữ liệu:'

+0

Cảm ơn Carl. Nhưng điều đó có thể phù hợp với bên trong một chức năng? Tôi là một người biết chữ và không có nhiều người trong lĩnh vực của tôi là R hiểu biết (đó là những người gói này là dành cho) .Điều này phải rất dễ sử dụng.Không có thêm các cuộc gọi đến bất cứ điều gì như 'readlines' –

+0

@ TylerRinker là bản cập nhật của tôi có ích không? –

+0

Có chứ. +1 –

Các vấn đề liên quan