2012-01-04 4 views
4

인터넷을 검색했지만 내 문제에 대한 해결책을 찾을 수 없었습니다. 나는 숫자와 문자의 데이터 프레임이 있습니다R 데이터 프레임 반복 요소

mydf <- data.frame(col1=c(1, 2, 3, 4), 
        col2 = c(5, 6, 7, 8), 
        col3 = c("a", "b", "c", "d"), stringsAsFactors = FALSE) 

mydf :

col1 col2 col3 
    1 5 a 
    2 6 b 
    3 7 c 
    4 8 d 

내가 오른쪽 반복을 줄 것이다 apply(mydf, 2, function(x) rep(x, each = 3))를 사용

col1 col2 col3 
    1 5 a 
    1 5 a 
    1 5 a 
    2 6 b 
    2 6 b 
    2 6 b 
    3 7 c 
    3 7 c 
    3 7 c 
    4 8 d 
    4 8 d 
    4 8 d 

이 점을 반복하고 싶지만 col1, col2 및 col3의 클래스는 각각 숫자, 숫자 및 문자로 보존하지 않습니다. 이것은 구성된 예제이며, 내 데이터 프레임의 각 열의 클래스를 설정하는 것은 약간 지루한 작업입니다.

클래스를 보존하면서 반복을 할 수있는 방법이 있습니까?

답변

4

이것은 불행한하고 (나도, 어쨌든) 예상치 못한 수준의 변환이다. 여기에 data.frame이 단지 특별한 목록이라는 사실을 사용하는 쉬운 해결 방법이 있습니다.

data.frame(lapply(mydf, function(x) rep(x, each = 3))) 

은 (질문자가 관찰 된 행동이 버그로보고되지해야하는 이유를 아는 사람?)

+0

그 트릭을 했어! 정말 고맙습니다! – Sisse

1

raster 패키지에 aggregatedisaggregate에서 살펴 보자.

# zexpand: analogous to disaggregate 

zexpand<-function(inarray, fact=2, interp=FALSE, ...) { 
# do same analysis of fact to allow one or two values, fact >=1 required, etc. 
fact<-as.integer(round(fact)) 
switch(as.character(length(fact)), 
      '1' = xfact<-yfact<-fact, 
      '2'= {xfact<-fact[1]; yfact<-fact[2]}, 
      {xfact<-fact[1]; yfact<-fact[2];warning(' fact is too long. First two values used.')}) 
if (xfact < 1) { stop('fact[1] must be > 0') } 
if (yfact < 1) { stop('fact[2] must be > 0') } 

bigtmp <- matrix(rep(t(inarray), each=xfact), nrow(inarray), ncol(inarray)*xfact, byr=T) #does column expansion 
bigx <- t(matrix(rep((bigtmp),each=yfact),ncol(bigtmp),nrow(bigtmp)*yfact,byr=T)) 
# the interpolation would go here. Or use interp.loess on output (won't 
# handle complex data). Also, look at fields::Tps which probably does 
# a much better job anyway. Just do separately on Re and Im data 
return(invisible(bigx)) 
} 
10

그것은 당신이 생각하는 것보다 훨씬 쉽다 : 또는 아래 내 수정 된 버전 zexpand를 사용합니다.

index <- rep(seq_len(nrow(mydf)), each = 3) 
mydf[index, ] 

이렇게하면 apply에서 암시 적으로 반복되는 것을 피할 수 있습니다.

+0

'zexpand'를 다시 쓸 시간 인 것 같습니다 :-) –

+0

여러분의 도움과 의견에 감사드립니다! – Sisse

1

나는 Richie Cotton의 대답을 정말 좋아합니다.

그러나 당신은 또한 단순히 rbind를 사용하고 순서를 변경할 수 있습니다.

res <-rbind(mydf,mydf,mydf) 
res[order(res[,1],res[,2],res[,3]),] 
2

그냥 다른 솔루션 :

mydf3 <- do.call(rbind, rep(list(mydf), 3)) 
0

패키지 mefadata.frame에 적용 rep을위한 좋은 래퍼와 함께 제공됩니다. 이것은 한 줄에 예를 들어 맞는 것입니다 :

mefa:::rep.data.frame(mydf, each=3)