2011-04-13 7 views
6

I는 다음과 같이 동작하는 함수를 작성하기 위해 노력하고있어로 데이터 프레임을 분할하지만, 매우 어려운 증명 :는 중복 dataframes

DF <- data.frame(x = seq(1,10), y = rep(c('a','b','c','d','e'),2)) 
> DF 
    x y 
1 1 a 
2 2 b 
3 3 c 
4 4 d 
5 5 e 
6 6 a 
7 7 b 
8 8 c 
9 9 d 
10 10 e 

>OverLapSplit(DF,nsplits=2,overlap=2) 
[[1]] 
    x y 
1 1 a 
2 2 b 
3 3 c 
4 4 d 
5 5 e 
6 6 a 

[[2]] 
    x y 
1 5 a 
2 6 b 
3 7 c 
4 8 d 
5 9 e 
6 10 a 

>OverLapSplit(DF,nsplits=1) 
[[1]] 
    x y 
1 1 a 
2 2 b 
3 3 c 
4 4 d 
5 5 e 
6 6 a 
7 7 b 
8 8 c 
9 9 d 
10 10 e 

>OverLapSplit(DF,nsplits=2,overlap=4) 
[[1]] 
    x y 
1 1 a 
2 2 b 
3 3 c 
4 4 d 
5 5 e 
6 6 a 
7 7 b 

[[2]] 
    x y 
1 4 e 
2 5 a 
3 6 b 
4 7 c 
5 8 d 
6 9 e 
7 10 a 

>OverLapSplit(DF,nsplits=5,overlap=1) 
[[1]] 
    x y 
1 1 a 
2 2 b 
3 3 c 

[[2]] 
    x y 
1 3 c 
2 4 d 
3 5 e 

[[3]] 
    x y 
1 5 e 
2 6 a 
3 7 b 

[[4]] 
    x y 
1 7 b 
2 8 c 
3 9 d 

[[5]] 
    x y 
1 8 d 
2 9 e 
3 10 f 

내가 당신 경우 어떻게 될지에 대해 많이 생각하지 않은 어쩌면 다음 OverLapSplit(DF,nsplits=2,overlap=1)

같은 시도 뭔가 :

[[1]] 
    x y 
1 1 a 
2 2 b 
3 3 c 
4 4 d 
5 5 e 

[[2]] 
    x y 
1 5 a 
2 6 b 
3 7 c 
4 8 d 
5 9 e 
6 10 a 

감사합니다!

+0

이 함수는 존재합니까? 아니면 가장자리 케이스 처리 방법을 모르십니까? – Chase

+0

@Chase 함수가 존재하지 않습니다. 내가 실행할 수있는 (그러나 우아하지 않은) 버전이 코딩되면, 나는 그것을 게시 할 것이다. – Zach

+0

@Zach는이 Q입니까? 당신의 이전 질문입니까? http://stackoverflow.com/q/5652058/429846 –

답변

6

같은 것을보십시오 :

OverlapSplit <- function(x,nsplit=1,overlap=2){ 
    nrows <- NROW(x) 
    nperdf <- ceiling((nrows + overlap*nsplit)/(nsplit+1)) 
    start <- seq(1, nsplit*(nperdf-overlap)+1, by= nperdf-overlap) 

    if(start[nsplit+1] + nperdf != nrows) 
     warning("Returning an incomplete dataframe.") 

    lapply(start, function(i) x[c(i:(i+nperdf-1)),]) 
} 

nsplit와 분할의 수! (nsplit = 1은 2 개의 데이터 프레임을 반환합니다). 오버랩 스플릿이 데이터 프레임에 실제로 들어 가지 않으면 불완전한 마지막 데이터 프레임을 렌더링하고 경고를 표시합니다.

> OverlapSplit(DF,nsplit=3,overlap=2) 
[[1]] 
    x y 
1 1 a 
2 2 b 
3 3 c 
4 4 d 

[[2]] 
    x y 
3 3 c 
4 4 d 
5 5 e 
6 6 a 

[[3]] 
    x y 
5 5 e 
6 6 a 
7 7 b 
8 8 c 

[[4]] 
    x y 
7 7 b 
8 8 c 
9 9 d 
10 10 e 

그리고 경고 한

> OverlapSplit(DF,nsplit=1,overlap=1) 
[[1]] 
    x y 
1 1 a 
2 2 b 
3 3 c 
4 4 d 
5 5 e 
6 6 a 

[[2]] 
    x y 
6 6 a 
7 7 b 
8 8 c 
9 9 d 
10 10 e 
NA NA <NA> 

Warning message: 
In OverlapSplit(DF, nsplit = 1, overlap = 1) : 
    Returning an incomplete dataframe. 
+0

첫 번째 원칙에서 +1 좋은 대답 --- 나는 너무 [게으른 | 어리 석다]. [* delete the delete] ;-) –

+0

@ Gavin Simpson : 제가 생각하기에 완벽한 워크 플로로 직접 답변을 게시했습니다. 개선의 여지가 있지만, 지금은 내 필요를 충족시킬 것입니다. 모든 제안을 주셔서 감사합니다! – Zach

+0

@Joris Meys "불완전한"겹치는 데이터 프레임을 포함하지 않으려면 어떻게해야할까요? (예 : 경고를 한 걸음 나아감) –

4

이 래티스 그래픽에서 싱글 아이디어를 사용하고 있으므로 간격을 생성하는 패키지 lattice에서 코드를 활용 한 다음에 원래 DF을 깰 수있는 루프를 사용하여 올바른 하위 집합.

의미가 정확히 무엇인지 알 수 없었습니다. overlap = 1 - 1 샘플/관찰에 의한 중복을 의미한다고 가정합니다. 그렇다면 아래 코드가이를 수행합니다.

OverlapSplit <- function(x, nsplits = 1, overlap = 0) { 
    stopifnot(require(lattice)) 
    N <- seq_len(nr <- nrow(x)) 
    interv <- co.intervals(N, nsplits, overlap/nr) 
    out <- vector(mode = "list", length = nrow(interv)) 
    for(i in seq_along(out)) { 
     out[[i]] <- x[interv[i,1] < N & N < interv[i,2], , drop = FALSE] 
    } 
    out 
} 

주는 :

> OverlapSplit(DF, 2, 2) 
[[1]] 
    x y 
1 1 a 
2 2 b 
3 3 c 
4 4 d 
5 5 e 
6 6 a 

[[2]] 
    x y 
5 5 e 
6 6 a 
7 7 b 
8 8 c 
9 9 d 
10 10 e 

> OverlapSplit(DF) 
[[1]] 
    x y 
1 1 a 
2 2 b 
3 3 c 
4 4 d 
5 5 e 
6 6 a 
7 7 b 
8 8 c 
9 9 d 
10 10 e 

> OverlapSplit(DF, 4, 1) 
[[1]] 
    x y 
1 1 a 
2 2 b 
3 3 c 

[[2]] 
    x y 
3 3 c 
4 4 d 
5 5 e 

[[3]] 
    x y 
6 6 a 
7 7 b 
8 8 c 

[[4]] 
    x y 
8 8 c 
9 9 d 
10 10 e 
+0

'overlap'의 정의에주의하십시오. 'co.intervals()'는 오버랩하는 샘플의 절대 수가 아닌 겹치는 부분을 원하기 때문에 상황에 따라 반올림 문제가있을 수 있습니다. 그런 일이 생기면 원하는 것보다 겹치기가 적어 지거나 겹치게됩니다. –

+0

+1 우 - 네! 나에게 그것을 해칠 격자 해킹을 생각하지 않았어. 좋은 사람 –

0

그냥 내가 여기서 뭘하고있어 분명히 무엇을하기 위해이 방법으로

#Load Libraries 
library(PerformanceAnalytics) 
library(quantmod) 

#Function to Split Data Frame 
OverlapSplit <- function(x,nsplit=1,overlap=0){ 
    nrows <- NROW(x) 
    nperdf <- ceiling((nrows + overlap*nsplit)/(nsplit+1)) 
    start <- seq(1, nsplit*(nperdf-overlap)+1, by= nperdf-overlap) 

    if(start[nsplit+1] + nperdf != nrows) 
     warning("Returning an incomplete dataframe.") 

    lapply(start, function(i) x[c(i:(i+nperdf-1)),]) 
} 

#Function to run regression on 30 days to predict the next day 
FL <- as.formula(Next(HAM1)~HAM1+HAM2+HAM3+HAM4) 
MyRegression <- function(df,FL) { 
    df <- as.data.frame(df) 
    model <- lm(FL,data=df[1:30,]) 
    predict(model,newdata=df[31,]) 
} 

#Function to roll the regression 
RollMyRegression <- function(data,ModelFUN,FL) { 
    rollapply(data, width=31,FUN=ModelFUN,FL, 
    by.column = FALSE, align = "right", na.pad = FALSE) 
} 

#Load Data 
data(managers) 

#Split Dataset 
split.data <- OverlapSplit(managers,2,30) 
sapply(split.data,dim) 

#Run rolling regression on each split 
output <- lapply(split.data,RollMyRegression,MyRegression,FL) 
output 
unlist(output) 

, 병렬로 마지막에 lapply을 대체 할 수 버전의 lapply 및 속도를 다소 늘리십시오.

물론 프로세서의 수와 데이터 세트의 크기를 고려할 때 스플릿/오버랩을 최적화하는 문제가 있습니다.