2012-01-04 15 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のための素晴らしいラッパーが付属しています。これはあなたの例を1行に収めます:

mefa:::rep.data.frame(mydf, each=3) 
関連する問題