2011-06-08 23 views
7

Me gustaría dividir un marco de datos en varios marcos de datos componentes basados ​​en los valores en una columna. En mi ejemplo, quiero dividir dat en dat.1, dat.2 y dat.3 usando los valores en la columna "cond". ¿Hay un comando simple que podría lograr esto?¿Cómo creo marcos de datos de componentes (subconjuntos) en R basados ​​en valores de columna?

dat 
sub cond trial time01 time02 
1 1 1 2774 8845 
1 1 2 2697 9945 
1 2 1 2219 9291 
1 2 2 3886 7890 
1 3 1 4011 9032 
2 2 1 3478 8827 
2 2 2 2263 8321 
2 3 1 4312 7576 
3 1 1 4219 7891 
3 3 1 3992 6674 


dat.1    
sub cond trial time01 time02 
1 1 1 2774 8845 
1 1 2 2697 9945 
3 1 1 4219 7891  

dat.2    
sub cond trial time01 time02 
2 2 1 3478 8827 
2 2 2 2263 8321 
1 2 1 2219 9291 
1 2 2 3886 7890 

dat.3    
sub cond trial time01 time02 
1 3 1 4011 9032 
2 3 1 4312 7576 
3 3 1 3992 6674 

Tal vez porque soy un novato R Todavía no he decidido cómo hacer esto a pesar de la navegación y de probar las soluciones propuestas en el foro de varias consultas similares. Gracias de antemano por cualquier respuesta.

Un dput() de los datos son:

structure(list(sub = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L 
), cond = c(1L, 1L, 2L, 2L, 3L, 2L, 2L, 3L, 1L, 3L), trial = c(1L, 
2L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 1L), time01 = c(2774L, 2697L, 
2219L, 3886L, 4011L, 3478L, 2263L, 4312L, 4219L, 3992L), time02 = c(8845L, 
9945L, 9291L, 7890L, 9032L, 8827L, 8321L, 7576L, 7891L, 6674L 
)), .Names = c("sub", "cond", "trial", "time01", "time02"), class = "data.frame", row.names = c(NA, 
-10L)) 

Respuesta

7

¿Hay algo que no se ajusten sobre

split(dat, dat$cond) 

? Tiene R y se divide como etiquetas, ya sabe ...

+1

+1 para el capitán obvio –

6

Sí, split(). Por ejemplo, si los datos están en dat, entonces:

with(dat, split(dat, cond)) 

devuelve una lista, cuyos componentes son las tramas de datos que quería:

R> with(dat, split(dat, cond)) 
$`1` 
    sub cond trial time01 time02 
1 1 1  1 2774 8845 
2 1 1  2 2697 9945 
9 3 1  1 4219 7891 

$`2` 
    sub cond trial time01 time02 
3 1 2  1 2219 9291 
4 1 2  2 3886 7890 
6 2 2  1 3478 8827 
7 2 2  2 2263 8321 

$`3` 
    sub cond trial time01 time02 
5 1 3  1 4011 9032 
8 2 3  1 4312 7576 
10 3 3  1 3992 6674 
+0

me ganas por un pelo! – Sam

+0

@Same @Nick nos ganó a ambos (yo por 12 segundos si los tiempos iniciales fueron correctos) –

+0

Gracias a todos los que respondieron. split() resolvió mi problema. Espero que en algún momento pueda ayudar a proporcionar asistencia de R. – dancingRobot

9

creo que la forma más fácil es a través de split:

split(dat, dat$cond) 

Nota sin embargo, esa división devuelve una lista de los data.frames.

Para obtener data.frames individuales de la lista se podría proceder como sigue usando un bucle para hacer que los objetos individuales (implícitos en la declaración lapply):

tmp <- split(dat, dat$cond) 
lapply(1:length(tmp), function(x) assign(paste("dat.", x, sep = ""), tmp[[x]], envir = .GlobalEnv)) 

Sin embargo, el uso de una lista es probablemente más R ish y será más útil a largo plazo.

¡Gracias a Gavin por publicar los datos!

+2

Salida 'dput()' agregada ... :-) –

4

Solo para completar, esta es una forma de hacerlo con el paquete plyr.

require(plyr) 

> dlply(dat, .(cond)) 
$`1` 
    sub cond trial time01 time02 
1 1 1  1 2774 8845 
2 1 1  2 2697 9945 
9 3 1  1 4219 7891 

$`2` 
    sub cond trial time01 time02 
3 1 2  1 2219 9291 
4 1 2  2 3886 7890 
6 2 2  1 3478 8827 
7 2 2  2 2263 8321 

$`3` 
    sub cond trial time01 time02 
5 1 3  1 4011 9032 
8 2 3  1 4312 7576 
10 3 3  1 3992 6674 

attr(,"class") 
[1] "split" "list" 

Nota la sencillez sintáctica en la que sólo se menciona una vez dat.

0

;)

ucond <- unique(dat$cond) 
dat_by_cond <- lapply(lapply(ucond, "==", dat$cond), subset, x=dat) 
names(dat_by_cond) <- paste("dat",ucond,sep=".") 
Cuestiones relacionadas