자신의 함수를 작성할 때 R의 줄임표 기능을 사용하는 방법은 무엇입니까?
R 언어에는 다양한 개수의 인수를 사용할 수있는 함수를 정의하는 멋진 기능이 있습니다. 예를 들어, 함수 data.frame
는 여러 인수를 사용하며 각 인수는 결과 데이터 테이블의 열에 대한 데이터가됩니다. 사용법 예 :
> data.frame(letters=c("a", "b", "c"), numbers=c(1,2,3), notes=c("do", "re", "mi"))
letters numbers notes
1 a 1 do
2 b 2 re
3 c 3 mi
함수의 서명에는 다음과 같은 줄임표가 포함됩니다.
function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE,
stringsAsFactors = default.stringsAsFactors())
{
[FUNCTION DEFINITION HERE]
}
비슷한 작업을 수행하는 함수를 작성하고 싶습니다. 여러 값을 가져 와서 단일 반환 값으로 통합하고 다른 처리를 수행합니다. 이렇게하려면 ...
함수 내에서 함수의 인수에서 "압축을 해제하는"방법을 찾아야 합니다. 나는 이것을하는 방법을 모른다. 의 함수 정의의 관련 라인 data.frame
입니다 object <- as.list(substitute(list(...)))[-1L]
내가 어떤 이해가되지 수있는.
어떻게 생략 부호를 함수의 서명에서 예를 들어 목록으로 변환 할 수 있습니까?
좀 더 구체적으로, get_list_from_ellipsis
아래 코드를 어떻게 작성할 수 있습니까?
my_ellipsis_function(...) {
input_list <- get_list_from_ellipsis(...)
output_list <- lapply(X=input_list, FUN=do_something_interesting)
return(output_list)
}
my_ellipsis_function(a=1:10,b=11:20,c=21:30)
편집하다
이를 수행하는 두 가지 가능한 방법이있는 것 같습니다. 그들은이다 as.list(substitute(list(...)))[-1L]
와 list(...)
. 그러나이 두 가지가 정확히 같은 것은 아닙니다. (차이점에 대해서는 답변의 예를 참조하십시오.) 누구든지 그들 사이의 실제적인 차이점과 사용해야 할 것을 말해 줄 수 있습니까?
답변과 의견을 읽었으며 언급되지 않은 내용은 거의 없습니다.
data.frame
list(...)
버전을 사용합니다 . 코드 조각 :object <- as.list(substitute(list(...)))[-1L] mrn <- is.null(row.names) x <- list(...)
object
열 이름으로 마술x
을 만드는 데 사용 되지만 final을 만드는 데 사용됩니다data.frame
.
평가되지 않은...
인수 를 사용하려면 사용 되는write.csv
코드를 확인하십시오match.call
.당신은 코멘트 결과에 Dirk 응답에 목록을 나열하지 않습니다. 길이가 4 인 요소의 목록입니다
language
. 첫 번째 개체는symbol
-list
이고 두 번째 개체는 식1:10
입니다.[-1L]
필요한 이유를 설명 합니다 :symbol
제공된 인수에서 예상 인수를 제거합니다...
(항상 목록이므로).
Dirk 상태substitute
에서 "평가되지 않은 구문 분석 트리"를 반환합니다.
당신이 호출 할 때my_ellipsis_function(a=1:10,b=11:20,c=21:30)
다음...
인수 목록을 "만들어"list(a=1:10,b=11:20,c=21:30)
하고substitute
그것을 네 가지 요소의 목록을 만들 :List of 4 $ : symbol list $ a: language 1:10 $ b: language 11:20 $ c: language 21:30
첫 번째 요소는 이름이 없으며 이것은
[[1]]
Dirk answer입니다. 다음을 사용 하여이 결과를 얻습니다.my_ellipsis_function <- function(...) { input_list <- as.list(substitute(list(...))) str(input_list) NULL } my_ellipsis_function(a=1:10,b=11:20,c=21:30)
위와 같이
str
함수에 어떤 객체가 있는지 확인할 수 있습니다 .my_ellipsis_function <- function(...) { input_list <- list(...) output_list <- lapply(X=input_list, function(x) {str(x);summary(x)}) return(output_list) } my_ellipsis_function(a=1:10,b=11:20,c=21:30) int [1:10] 1 2 3 4 5 6 7 8 9 10 int [1:10] 11 12 13 14 15 16 17 18 19 20 int [1:10] 21 22 23 24 25 26 27 28 29 30 $a Min. 1st Qu. Median Mean 3rd Qu. Max. 1.00 3.25 5.50 5.50 7.75 10.00 $b Min. 1st Qu. Median Mean 3rd Qu. Max. 11.0 13.2 15.5 15.5 17.8 20.0 $c Min. 1st Qu. Median Mean 3rd Qu. Max. 21.0 23.2 25.5 25.5 27.8 30.0
It's ok. Lets see
substitute
version:my_ellipsis_function <- function(...) { input_list <- as.list(substitute(list(...))) output_list <- lapply(X=input_list, function(x) {str(x);summary(x)}) return(output_list) } my_ellipsis_function(a=1:10,b=11:20,c=21:30) symbol list language 1:10 language 11:20 language 21:30 [[1]] Length Class Mode 1 name name $a Length Class Mode 3 call call $b Length Class Mode 3 call call $c Length Class Mode 3 call call
Isn't what we needed. You will need additional tricks to deal with these kind of objects (as in
write.csv
).
If you want use ...
then you should use it as in Shane answer, by list(...)
.
You can convert the ellipsis into a list with list()
, and then perform your operations on it:
> test.func <- function(...) { lapply(list(...), class) }
> test.func(a="b", b=1)
$a
[1] "character"
$b
[1] "numeric"
So your get_list_from_ellipsis
function is nothing more than list
.
A valid use case for this is in cases where you want to pass in an unknown number of objects for operation (as in your example of c()
or data.frame()
). It's not a good idea to use the ...
when you know each parameter in advance, however, as it adds some ambiguity and further complication to the argument string (and makes the function signature unclear to any other user). The argument list is an important piece of documentation for function users.
Otherwise, it is also useful for cases when you want to pass through parameters to a subfunction without exposing them all in your own function arguments. This can be noted in the function documentation.
Just to add to Shane and Dirk's responses: it is interesting to compare
get_list_from_ellipsis1 <- function(...)
{
list(...)
}
get_list_from_ellipsis1(a = 1:10, b = 2:20) # returns a list of integer vectors
$a
[1] 1 2 3 4 5 6 7 8 9 10
$b
[1] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
with
get_list_from_ellipsis2 <- function(...)
{
as.list(substitute(list(...)))[-1L]
}
get_list_from_ellipsis2(a = 1:10, b = 2:20) # returns a list of calls
$a
1:10
$b
2:20
As it stands, either version appears suitable for your purposes in my_ellipsis_function
, though the first is clearly simpler.
You gave half the answer already. Consider
R> my_ellipsis_function <- function(...) {
+ input_list <- as.list(substitute(list(...)))
+ }
R> print(my_ellipsis_function(a=1:10, b=2:20))
[[1]]
list
$a
1:10
$b
11:20
R>
So this took two arguments a
and b
from the call and converted it to a list. Wasn't that what you asked for?
This works as expected. The following is an interactive session:
> talk <- function(func, msg, ...){
+ func(msg, ...);
+ }
> talk(cat, c("this", "is", "a","message."), sep=":")
this:is:a:message.
>
Same, except with a default argument:
> talk <- function(func, msg=c("Hello","World!"), ...){
+ func(msg, ...);
+ }
> talk(cat,sep=":")
Hello:World!
> talk(cat,sep=",", fill=1)
Hello,
World!
>
As you can see, you can use this to pass 'extra' arguments to a function within your function if the defaults are not what you want in a particular case.
'Programing' 카테고리의 다른 글
장고의 한 페이지에서 여러 양식을 처리하는 올바른 방법 (0) | 2020.05.23 |
---|---|
pip install --user로 설치된 패키지를 제거하는 방법 (0) | 2020.05.23 |
REST API 로그인 패턴 (0) | 2020.05.23 |
std :: map이 레드-블랙 트리로 구현 된 이유는 무엇입니까? (0) | 2020.05.23 |
숭고한 텍스트 2 줄 끝을 수정? (0) | 2020.05.23 |