2012-07-27 13 views
22

मैं एक data.frame df है के लिए expand.grid करने के लिए और मुझे लगता है कि इस df में हर पंक्ति दोहराया गया है चाहते हैं lengthTime बार और कहा कि एक नया स्तंभ जोड़ दिया जाता है कि df में प्रत्येक पंक्ति के लिए 1 से lengthTime लिए मायने रखता है ।वैकल्पिक data.frames

मुझे पता है, यह बहुत जटिल लगता है, लेकिन जो मैं मूल रूप से चाहता हूं वह expand.grid से df पर लागू करना है। यहाँ एक बदसूरत समाधान नहीं है और मैं लग रहा है कि अधिकांश एक आसान समाधान हो है (हो सकता है यहां तक ​​कि एक आधार-आर समारोह?):

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) 

मैंने सोचा था कि मैं सिर्फ expand.grid(df, 1:lengthTime) इस्तेमाल कर सकते हैं, लेकिन यह काम नहीं करता। outer या तो कोई भाग्य नहीं लाया। तो क्या कोई भी एक अच्छा समाधान जानता है?

उत्तर

13

डेटा फ्रेम का विस्तार करने के लिए df[rep(1:nrow(df),times = 3),] की तरह कुछ क्यों नहीं, और फिर ऊपर दिए गए अतिरिक्त कॉलम को df$Time <- rep(1:lengthTime, each=nrRow) के साथ जोड़ें?

2

यह काम करता है:

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

मेरा वास्तव में जोरन से अलग नहीं है जो मुझे 40 सेकंड तक मारता है लेकिन मैं इसे छोड़ दूंगा क्योंकि यह थोड़ा और स्पष्ट है। –

+0

पहले आओ, पहले सेवा करें, इसलिए मैंने उसका जवाब स्वीकार कर लिया ;-) लेकिन आप दोनों के लिए +1। यह एक बहुत साफ समाधान है! –

36

यह एक समय हो गया है के बाद से इस सवाल का पोस्ट किया गया था, लेकिन मैं हाल ही में यह भर में आया शीर्षक में सिर्फ बात की तलाश में, अर्थात्, एक expand.grid कि डेटा फ्रेम के लिए काम करता है। पोस्ट जवाब ओपी के अधिक विशिष्ट प्रश्न का समाधान है, तो इस मामले में किसी को भी डेटा फ्रेम के लिए एक अधिक सामान्य समाधान की तलाश में है, यहाँ एक से थोड़ा अधिक सामान्य दृष्टिकोण है:

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

सुंदर समाधान। – Ariel

+1

वाह। यह बहुत अच्छा काम है। – jknowles

9

तुम भी सिर्फ एक सरल merge रूप NULL उपयोग कर सकते हैं स्तंभ (जो merge कारण सरल मिश्रित डेटा प्रतिकृति करने के लिए होगा) विलय:

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

पाइपिंग ऑपरेटर %>%magrittr पैकेज से आता है (dplyr भी यह स्वचालित रूप से जोड़ देती है) और बस impro करने के लिए इस्तेमाल किया गया था पठनीयता तुम भी सरल कर सकते हैं merge(iris, data.frame(...), by=NULL)

+0

मुझे लगता है कि आप यह उल्लेख करना चाहेंगे कि आपने '%>%' से ... –

+0

@ डेविड एडनबर्ग संकेत के लिए धन्यवाद। –

1

एक data.table समाधान:

> 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 

एक और एक:

> 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

त्वरित अद्यतन

अब है भी पार() पैकेज tidyr में समारोह जो मर्ज करने के बजाए इस्तेमाल किया जा सकता है, कुछ हद तक तेज़ है, और एक tbl_df/tibble देता है।

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

data.frame(time=1:10) %>% tidyr::crossing(iris) 
संबंधित मुद्दे