2012-02-17 3 views
31

고유 한 벡터화 된 특성과 관련된 R의 좋은 특징 중 하나는 2.2 절의 An Introduction to R에 설명 된 재활용 규칙입니다.표준 재활용 규칙의 구현

동일한 표현에서 발생하는 벡터는 모두 동일한 길이 일 필요는 없다. 그렇지 않은 경우 표현식의 값은 표현식에서 발생하는 가장 긴 벡터와 길이가 같은 벡터입니다. 표현의 짧은 벡터는 재활용 된으로 가장 긴 벡터의 길이와 일치 할 때까지 (아마도 부분적으로) 필요할 수 있습니다. 특히 상수는 단순히 반복됩니다.

대부분의 표준 함수는 이것을 사용하지만, 그렇게하는 코드는 기본 C 코드에 묻혀 있습니다.

함수에 대한 표준 재활용 규칙을 R 코드로 구현하는 표준 방법이 있습니까? 즉,이 a, bc 아마도 서로 다른 길이와 알 수없는 유형/클래스의 벡터이다

mock <- function(a, b, c) { 
    # turn a, b, and c into appropriate recycled versions 

    # do something with recycled a, b, and c in some appropriately vectorized way 
} 

같은 기능을 부여, 따라 재활용 벡터의 새로운 세트를 얻을 수있는 표준 방법이 표준 재활용 규칙에 맞습니까? 특히, "무언가를하십시오"단계가 적절한 재활용을 수행 할 것이라고 가정 할 수 없으므로 사전에 직접 처리해야합니다.

답변

20

,

expand_args <- function(...){ 
    dots <- list(...) 
    max_length <- max(sapply(dots, length)) 
    lapply(dots, rep, length.out = max_length) 
} 
+0

+1 우리의 아이디어는 본질적으로 동일하지만, 당신은 그것을 핵심으로 파싱하는 것이 더 낫습니다. (당신의 대답을보고, 나는 데이터를 구성하는 데 약간의 어려움이있었습니다. 프레임 예제!) –

+0

원래 답변을 게시했을 때 상당히 달랐지만 이제는 이름과 거의 동일합니다. – baptiste

+0

그래, 알겠지만 실질적으로 유사한 버전이 몇 분만에 서로의 기능을 사용할 수 있습니다. 둘. –

7

실제 작업의 대부분을 수행하려면 length.out 인수를 rep()으로 사용하고 싶습니다.

다음은 better.data.frame() 함수 (실제로는 "better".data.frame()이라고해야 함)를 만드는 예제입니다.이 함수는 인수로 전달되는 벡터의 길이를 제한하지 않습니다. 이 경우, 모든 벡터를 가장 긴 길이로 재활용하지만, 분명히 자신의 재활용 요구에 맞출 수 있습니다! 수치 인수

내가 과거에 이것을 사용했습니다
better.data.frame <- function(...) { 
    cols <- list(...) 
    names(cols) <- sapply(as.list(match.call()), deparse)[-1] 

    # Find the length of the longest vector 
    # and then recycle all columns to that length. 
    n <- max(sapply(cols, length)) 
    cols <- lapply(cols, rep, length.out = n) 

    as.data.frame(cols) 
} 

# Try it out 
a <- Sys.Date() + 0:9 
b <- 1:3 
c <- letters[1:4] 

data.frame(a,b,c) 
# Error in data.frame(a, b, c) : 
# arguments imply differing number of rows: 10, 3, 4 

better.data.frame(a,b,c) 
#    a b c 
# 1 2012-02-17 1 a 
# 2 2012-02-18 2 b 
# 3 2012-02-19 3 c 
# 4 2012-02-20 1 d 
# 5 2012-02-21 2 a 
# 6 2012-02-22 3 b 
# 7 2012-02-23 1 c 
# 8 2012-02-24 2 d 
# 9 2012-02-25 3 a 
# 10 2012-02-26 1 b 
+0

가장 긴 인수가 첫 번째가 아닌 경우를 처리하도록'n <--'을 사용할 수 있습니다. 'a <- rep (a, length.out = n)'을 추가하십시오. – Justin

+0

@Justin - 고마워요. . 그냥 그 일을하고, 임의의 수의 인수 걸릴 함수를 일반화했다. 만약 당신 (또는 다른 사람) 함수 호출 내부에서 제공된 인수의 이름을 내게 더 나은 방법을 참조하십시오. 저에게 알려주세요. 그게 바로 제가 배웠던 바로 그 것입니다 ... –

0

한 더러운 단기 및-노선은 cbind의 자동 재활용에 의존하는 것입니다. 예를 들면 다음과 같습니다.

f.abc <- function(a,b,c) { 

    df.abc <- as.data.frame(suppressWarnings(cbind(a=a, b=b, c=c))) 

    #Then use, for example, with() to use a, b and c inside the data frame, 
    #or apply(df.abc,1, ...) 
} 

경고에 대한 다른 합법적 인 원인이 전혀 없습니다.

관련 문제