2011-12-28 36 views
6

Loại đối tượng nào được chuyển đến myFunc là x? Nó không có vẻ là một biểu thức, cũng không phải là một hàm và str chỉ đánh giá nó. Tôi hiểu rằng tôi có thể sử dụng force() để đánh giá. Tôi tự hỏi nếu có một số cách để thu thập thêm thông tin về x mà không đánh giá nó.R - Phát hiện các biểu thức

myFunc = function(x) 
{ 
    is.expression(x)  
    is.function(x) 
    str(x) 
} 
myFunc({ x = 5; print(x + 1) }) 
+1

gì về lớp (x) – Benjamin

+0

dường như không báo cáo nó như là một biểu thức. không gõ() cũng không chế độ() – SFun28

+0

Tôi nghĩ bạn có thể bị lẫn lộn giữa các biểu thức (về cơ bản là danh sách các cuộc gọi không được đánh giá) và kết quả của một biểu thức. 'x' trong hàm của bạn là 6. – hadley

Trả lời

6

bạn có thể sử dụng match.call để trích xuất các đối số:

myFunc <- function(x) { 
    x <- match.call()$x 
    print(class(x)) 
    print(typeof(x)) 
    print(mode(x)) 
    print(storage.mode(x)) 
    print(is.expression(x)) 
    print(is.call(x)) 
    if (is.call(x)) print(x[[1]]) 
} 
myFunc({x = 5; print("a")}) 
myFunc(expression(x)) 
x <- factor(1) 
myFunc(x) 
myFunc(1) 

có lẽ tôi cần phải nói rằng { là một chức năng trong R, vì vậy {...} là không quá call.

Cập nhật: tại sao x không function khi {function:

f <- function(x) { 
    x <- match.call()$x 
    print(eval(x[[1]])) 
    print(is.function(eval(x[[1]]))) 
} 

f({1}) 
+0

cảm ơn cho việc này với nhau! Nếu {là một chức năng, thì tại sao is.function (x) trả về FALSE? Có cách nào để thay đổi môi trường của x? – SFun28

+0

vì x là 'cuộc gọi', không phải' hàm'. 'Cuộc gọi' bao gồm' hàm' và 'đối số'. Xem thêm cập nhật. – kohske

2

Tôi nghĩ class sẽ thực hiện thủ thuật ... Xem docs.

EDIT: Theo docs,

cho {, kết quả của biểu thức cuối cùng đánh giá

Có nghĩa lớp là lớp phát sinh từ việc đánh giá, đó là lý do tại sao nó không hiển thị như là một "biểu hiện". Nó đang được thông qua sau khi đánh giá.

+0

Hmmm,' class' trả về 'số' làm cho tôi nghĩ rằng nó thực sự đánh giá biểu thức trước khi kiểm tra ... – nico

+0

Thực ra, ngay cả khi bạn cố gắng gán biểu thức đó cho một biến, biểu thức là chạy ngay lập tức, và bạn kết thúc với một biến số có chứa 6 ... – nico

+0

Chính xác. Việc đánh giá được thực hiện ngay lập tức, trước khi chuyển nhượng hoặc chuyển kết quả đến một hàm. – Benjamin

1

Dason vừa mới công bố một phản ứng tương tự như sau trên Talkstats.com để xác định nếu một đối tượng là một khung dữ liệu hoặc một danh sách (click here for a link to that post). Tôi chỉ mở rộng nó vào một biểu hiện mà tôi nghĩ phù hợp với nhu cầu của bạn.

j.list <- function(list, by = NULL){ 
    print("list") 
    print(list) 
} 

j.data.frame <- function(df, ..., by = NULL){ 
    print("data frame") 
    print(df) 
} 


j.expression <- function(expression, by = NULL){ 
    print("expression") 
    print(expression) 
} 

j <- function(x, ...){ 
    UseMethod("j") 
} 

j(list(test = "this is a list")) 
j(data.frame(test = 1:10)) 
j(expression(1+ 0:9)) 
+0

j ({x = 5; print (x + 1)}) ném lỗi "không áp dụng phương thức 'j' cho đối tượng của lớp" c ('double', 'numeric') "nhưng giải pháp có vẻ thông minh =) – SFun28

+0

Nó không nhất thiết phải xác định xem một cái gì đó là một khung dữ liệu hay một danh sách - nó là để điều chỉnh cuộc gọi hàm cho dù đối số là một khung dữ liệu hay danh sách vì áp phích muốn có khả năng cung cấp chức năng tương tự cho cả hai trường hợp nhưng muốn chức năng cho biết nếu đối tượng được truyền vào là một danh sách hoặc khung dữ liệu.Nhưng cảm ơn cho shoutout – Dason

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