2015-03-08 15 views
6

Tôi muốn cung cấp một biến tùy chọn cho hàm, cho phép các hàm kiểm tra xem đối số này có được cung cấp hay không tính toán. Tôi nghĩ tôi có thể sử dụng toán tử '...' cho điều đó.R: Tìm các biến được cung cấp cho các hàm có đối số '...' với tồn tại()

Ví dụ đơn giản nhất tôi có thể nghĩ đến (mà buồn bã thất bại) là thế này:

monkeyfun = function(...){ 

    if (exists("monkey")){ 
     return('monkey found') 
    } else { 
     return('monkey not found') 
    } 

    } 

Bây giờ monkeyfun(monkey=0) cũng như monkeyfun() cả trở "monkey not found".

Để kiểm tra tính chính xác, xác định monkey = 1 bên ngoài chức năng hoạt động và trả về "monkey found".

Tài liệu về đối số '...' không thực sự giúp tôi hiểu vấn đề này và tôi không thể tìm thấy công thức cho câu hỏi này cho kết quả phù hợp ở đây (tôi hiểu câu hỏi này là cơ bản và có thể thảo luận ở đâu đó) ...

Tôi thực sự đánh giá cao một số trợ giúp về vấn đề này.

Trả lời

5

Tôi sẽ sử dụng hasArg:

monkeyfun <- function(...) { 
    if (hasArg("monkey")) { 
    return('monkey found') 
    } else { 
    return('monkey not found') 
    } 
} 
monkeyfun() 
# [1] "monkey not found" 
monkeyfun(monkey=0) 
# [1] "monkey found" 
+0

rõ ràng là lựa chọn tốt nhất – BrodieG

+0

Tôi đã chơi xung quanh với 'hasArg()' chỉ bây giờ ... nó cho thấy hành vi bất ngờ sau đây mặc dù ... có chức năng sau đây: 'tfun = function (x = 0) {if (hasArg (name = 'x')) {print ('found')}} ' Nếu tôi chạy nó mà không cung cấp' x' (mặc dù nó sẽ kích hoạt mặc định), nó không cho tôi biết '' tìm thấy "'. – Affaeng

+0

@Affaeng: tại sao điều đó bất ngờ? Nếu bạn gọi 'tfun()' không có đối số, thì không có đối số 'x' trong cuộc gọi. Vì vậy, 'hasArg (" x ")' khá chính xác trả về 'FALSE'. Nó không liên quan là 'x' là một đối số chính thức cho' tfun'. Như đã đề cập trong phần * Xem thêm * với '? HasArg', bạn có thể muốn đọc'? Missing'. –

1

Điều này liên quan đến cách đánh giá phi tiêu chuẩn hoạt động trong R (http://adv-r.had.co.nz/Computing-on-the-language.html#capturing-dots). Bạn có thể in danh sách các đối tượng được chuyển đến hàm bằng cách sử dụng ... sử dụng print(list(...)), bạn có thể đánh giá chúng bằng cách sử dụng eval(substitute(alist(...))). Trong trường hợp của bạn, bạn muốn kiểm tra xem một đối tượng có được xác định trong ... hay không. Điều này có thể được thực hiện bằng mã sau đây.

monkeyfun = function(...){ 
print(list(...)) 
    if ("monkey"%in%names(list(...))){ 
    return('monkey found') 
    } else { 
    return('monkey not found') 
    } 

} 
+4

Cơ chế cung cấp bởi Hadley không phải là thực hành R điển hình. Nó là điển hình hơn để gán kết quả của 'list (...)' vào một tên và sau đó làm việc với đối tượng đó, có lẽ kết hợp với 'match.arg'. Tôi cũng không nghĩ rằng điều này có liên quan nhiều đến việc đánh giá phi tiêu chuẩn –

3

Hãy xem hộp thoại này với trình thông dịch R. Nói chung tồn tại được kiểm tra bằng cách nhìn thấy nếu chiều dài lớn hơn 0:

monkeyfun = function(...){ 
print(str(list(...))) 
    } 
monkeyfun(monkey=0) 
#List of 1 
# $ monkey: num 0 
#NULL 
monkeyfun = function(...){ 
loclist = list(...) 
    if (exists(loclist$monkey)){ 
     return('monkey found') 
     } else { 
     return('monkey not found') 
     } } 
monkeyfun(monkey=0) 
#Error in exists(loclist$monkey) : invalid first argument 
monkeyfun = function(...){ 
loclist = list(...) 
    if (length(loclist$monkey)){ 
     return('monkey found') 
     } else { 
     return('monkey not found') 
     } } 
monkeyfun(monkey=0) 
#[1] "monkey found" 
monkeyfun(monk_uncle=1) 
#[1] "monkey not found" 
4

Tôi sẽ sử dụng match.call vì nó trả về tất cả các đối số chức năng được xác định bởi tên đầy đủ của họ. Dưới đây Làm thế nào tôi sẽ viết lại chức năng của bạn:

monkeyfun = function(...){ 
    params <- as.list(match.call()[-1]) 
    if ("monkey" %in% names(params)){ ## note how I change the test here 
    return('monkey found') 
    } else { 
    return('monkey not found') 
    } 

} 

# monkeyfun() 
# [1] "monkey not found" 
# > monkeyfun(monkey=0) 
# [1] "monkey found" 
+0

Cảm ơn bạn rất nhiều! – Affaeng

+0

Tôi nghĩ rằng 'params <- list (...)' là một chút đơn giản và dễ hiểu hơn. Tôi tin rằng nó sẽ làm việc giống nhau ở đây. –

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