2014-12-03 9 views
6

Sono relativamente nuovo a R e vorrei sapere come posso creare una variabile (sequenza numerica) che identifica ciascuno dei dati originali. prima di essere unito al comando rbind.Crea una variabile che identifica il data.frame originale dopo il comando rbind in R

Poiché nei frame di dati originali c'è una variabile che è un numero ID di riga, se si crea un ciclo che assegna un nuovo numero nella nuova variabile ogni volta che incontra il numero 1 nell'ID di riga, dovrebbe funzionare. ..

Grazie.

risposta

5

C'è una funzione nel pacchetto gdata chiamato combine che fa proprio questo.

df1 <- data.frame(a = seq(1, 5, by = 1), 
        b = seq(21, 25, by = 1)) 

df2 <- data.frame(a = seq(6, 10, by = 1), 
        b = seq(26, 30, by = 1)) 

library(gdata) 
combine(df1, df2) 

    a b source 
1 1 21 df1 
2 2 22 df1 
3 3 23 df1 
4 4 24 df1 
5 5 25 df1 
6 6 26 df2 
7 7 27 df2 
8 8 28 df2 
9 9 29 df2 
10 10 30 df2 
2

Perché non basta:

rbind(cbind(df1, origin="df1"), 
      cbind(df2, origin='df2')) 

Oppure, se si desidera conservare rownames:

rbind(cbind(df1, origin=paste("df1",rownames(df1), sep="_")), 
     cbind(df2, origin=paste("df1",rownames(df1), sep="_"))) 
2

È possibile utilizzare

transform(dat, newCol = cumsum(ID == 1)) 

dove dat è il nome della vostra cornice di dati e ID è il nome della colonna ID.

1

Una soluzione abbastanza estendibile:

# test data: 
df1 <- data.frame(id=letters[1:2]) 
df2 <- data.frame(id=letters[1:2]) 

Raccogliere i dati in una lista poi rbind tutti in una volta:

dfs <- c("df1","df2") 
do.call(rbind, Map("[<-", mget(dfs), TRUE, "source", dfs)) 

#  id source 
#df1.1 a df1 
#df1.2 b df1 
#df2.1 a df2 
#df2.2 b df2 

Inoltre, nota in questo esempio che quando si rbind utilizzando un lista nominata, i tuoi nomi utente fanno riferimento ai dati di origine. Ciò significa che puoi quasi ottenere ciò che vuoi semplicemente usando:

dfs <- c("df1","df2") 
do.call(rbind, mget(dfs)) 

#  id 
#df1.1 a 
#df1.2 b 
#df2.1 a 
#df2.2 b 
0

Grazie a tutti! Ho finito con una soluzione semplice lavorare con un mio amico con la creazione di un indice, in questo modo:

index<-rep(1,times=nrow(data.frame)) 

for (i in 1:(nrow(data.frame)-1)){ 

if (data_frame$ID [i+1]<= data.frame$ID[i]) { 
index[i+1]<-index[i]+1 
} 
else {index[i+1]<-index[i]}} 

new.data.frame <- cbind(index, data.frame) 
6

Sembra bind_rows dal pacchetto dplyr farà anche questo. Utilizzando l'esempio di maloneypatr:

df1 <- data.frame(a = seq(1, 5, by = 1), 
        b = seq(21, 25, by = 1)) 

df2 <- data.frame(a = seq(6, 10, by = 1), 
        b = seq(26, 30, by = 1)) 

dplyr::bind_rows(df1, df2, .id = "source") 

Source: local data frame [10 x 3] 

# source  a  b 
#  (chr) (dbl) (dbl) 
# 1  1  1 21 
# 2  1  2 22 
# 3  1  3 23 
# 4  1  4 24 
# 5  1  5 25 
# 6  2  6 26 
# 7  2  7 27 
# 8  2  8 28 
# 9  2  9 29 
# 10  2 10 30