2012-07-27 15 views
22

data.frames için expand.grid için ve ben bu df her satır yinelenmiş bu lengthTime kez istiyor ve bu yeni bir sütun eklenir o df her satır için 1'den lengthTime için sayımları .Alternatif Bir data.frame <code>df</code> var

Biliyorum, oldukça karmaşık görünüyor, ancak temel olarak istediğim 'u df'a uygulamaktır. İşte çirkin bir geçici çözüm ve daha kolay bir çözüm olması çoğu o duygu var (belki de bir baz-R fonksiyonu?):

df <- data.frame(ID = rep(letters[1:3], each=3), 
       CatA = rep(1:3, times = 3), 
       CatB = letters[1:9]) 
lengthTime <- 3 
nrRow <- nrow(df) 
intDF <- df 
for (i in 1:(lengthTime - 1)) { 
    df <- rbind(df, intDF) 
} 
df$Time <- rep(1:lengthTime, each=nrRow) 

Ben sadece expand.grid(df, 1:lengthTime) kullanabilirsiniz düşündüm, ama bu işe yaramaz. outer da hiçbir şans getirmedi. Peki herkes iyi bir çözüm biliyor mu?

cevap

13

Neden veri çerçevesini uzatmak için gibi bir şey yapmıyorsunuz ve daha sonra yukarıdaki gibi ek sütun eklemek df$Time <- rep(1:lengthTime, each=nrRow)?

2

Bu çalışır: bu soru yayınlanmıştır beri

REP <- rep(1:nrow(df), 3) 
df2 <- data.frame(df[REP, ], Time = rep(1:3, each = 9)) 
rownames(df2) <- NULL 
df2 
+0

Mine gerçekten Joran 40 bazı saniye ile yendin ama biraz daha açık olduğu gibi ben bırakacağım kimin daha farklı değildir. –

+0

İlk önce, önce gelsin, ben de onun cevabını kabul ettim ;-) İkiniz için +1 +. Bu çok temiz bir çözüm! –

36

Bir süre oldu, ama son zamanlarda başlığında şeyi bulmak için seyir karşıya geldi, yani veri çerçeveleri için çalışan bir expand.grid. Ayrıca tıpkı NULL kullanarak basit merge yapabilirsiniz

expand.grid.df <- function(...) Reduce(function(...) merge(..., by=NULL), list(...)) 

# For the example in the OP 
expand.grid.df(df, data.frame(1:lengthTime)) 

# More generally 
df1 <- data.frame(A=1:3, B=11:13) 
df2 <- data.frame(C=51:52, D=c("Y", "N")) 
df3 <- data.frame(E=c("+", "-")) 
expand.grid.df(df1, df2, df3) 
+1

Güzel çözüm. – Ariel

+1

Vay. Bu harika bir iş. – jknowles

9

: yayınlanmıştır cevaplar durumda herkes veri çerçevelerinin daha genel bir çözüm arıyorsanız bu yüzden, OP'ın daha spesifik soruyu ele, burada biraz daha genel bir yaklaşım (basit birleştirici veri çoğaltma yapmak merge neden olacaktır) sütun birleştirme:

data.frame(time=1:lengthTime) %>% merge(iris, by=NULL) 

operatör %>%magrittr paketinden geliyor boru (dplyr da otomatik olarak ekler) ve sadece doğaçlama için kullanıldı okunabilirlik. Ayrıca, basit yapabilirsiniz merge(iris, data.frame(...), by=NULL)

+0

Sanırım%>% 'den nereye gittiğinizi belirtmek isteyebilirsiniz ... –

+0

@DavidArenburg ipucu için teşekkürler. –

1

A data.table çözüm:

> library(data.table) 
> (df <- data.frame(ID = rep(letters[1:3], each=3), 
+     CatA = rep(1:3, times = 3), 
+     CatB = letters[1:9])) 
    ID CatA CatB 
1 a 1 a 
2 a 2 b 
3 a 3 c 
4 b 1 d 
5 b 2 e 
6 b 3 f 
7 c 1 g 
8 c 2 h 
9 c 3 i 
> (DT <- data.table(df)[, lapply(.SD, function(x) rep(x,3))][, Time:=rep(1:3, each=nrow(df0))]) 
    ID CatA CatB Time 
1: a 1 a 1 
2: a 2 b 1 
3: a 3 c 1 
4: b 1 d 1 
5: b 2 e 1 
6: b 3 f 1 
7: c 1 g 1 
8: c 2 h 1 
9: c 3 i 1 
10: a 1 a 2 
11: a 2 b 2 
12: a 3 c 2 
13: b 1 d 2 
14: b 2 e 2 
15: b 3 f 2 
16: c 1 g 2 
17: c 2 h 2 
18: c 3 i 2 
19: a 1 a 3 
20: a 2 b 3 
21: a 3 c 3 
22: b 1 d 3 
23: b 2 e 3 
24: b 3 f 3 
25: c 1 g 3 
26: c 2 h 3 
27: c 3 i 3 

Diğeri:

> library(data.table) 
> (df <- data.frame(ID = rep(letters[1:3], each=3), 
+     CatA = rep(1:3, times = 3), 
+     CatB = letters[1:9])) 
> DT <- data.table(df) 
> rbindlist(lapply(1:3, function(i) cbind(DT, Time=i))) 
    ID CatA CatB Time 
1: a 1 a 1 
2: a 2 b 1 
3: a 3 c 1 
4: b 1 d 1 
5: b 2 e 1 
6: b 3 f 1 
7: c 1 g 1 
8: c 2 h 1 
9: c 3 i 1 
10: a 1 a 2 
11: a 2 b 2 
12: a 3 c 2 
13: b 1 d 2 
14: b 2 e 2 
15: b 3 f 2 
16: c 1 g 2 
17: c 2 h 2 
18: c 3 i 2 
19: a 1 a 3 
20: a 2 b 3 
21: a 3 c 3 
22: b 1 d 3 
23: b 2 e 3 
24: b 3 f 3 
25: c 1 g 3 
26: c 2 h 3 
27: c 3 i 3 
5

Hızlı güncelleme

paket tidyr da geçiş() fonksiyonu artık yoktur ki Birleştirme yerine kullanılabilir, biraz daha hızlıdır ve bir tbl_df/tibble döndürür.

data.frame(time=1:10) %>% merge(iris, by=NULL) 

data.frame(time=1:10) %>% tidyr::crossing(iris)