2012-09-28 16 views
5

tengo estos datos:Convertir una hoja.de.datos en una sola fila

structure(list(type = c("journal", "all", "similar_age_1m", "similar_age_3m", 
"similar_age_journal_1m", "similar_age_journal_3m"), count = c("13972", 
"754555", "22408", "56213", "508", "1035"), rank = c("13759", 
"754043", "22339", "56074", "459", "947"), pct = c("98.48", "99.93", 
"99.69", "99.75", "90.35", "91.50")), .Names = c("type", "count", 
"rank", "pct"), row.names = c(NA, -6L), class = "data.frame") 

me gustaría convertirlo en una sola fila, con los nombres de las columnas 2:4 prefijadas por el tipo correspondiente. p.ej. journal.count, journal.rank ... ¿Cuál es la forma más rápida de hacer esto? Por alguna razón, dcast y reshape no lo hacen por mí y mi solución es un poco engorrosa.

+0

No entiendo donde "recuento" y "rango" provienen de – GSee

+0

lo arreglé y actualizada la cuestión. – Maiasaura

Respuesta

5

Usted ha mencionado reshape2, asi que aquí hay una manera de que:

library("reshape2") 
dcast(melt(dat, id.var="type"), 1~variable+type) 

Eso da:

1 count_all count_journal count_similar_age_1m count_similar_age_3m 
1 1 754555   13972    22408    56213 
    count_similar_age_journal_1m count_similar_age_journal_3m rank_all 
1       508       1035 754043 
    rank_journal rank_similar_age_1m rank_similar_age_3m 
1  13759    22339    56074 
    rank_similar_age_journal_1m rank_similar_age_journal_3m pct_all pct_journal 
1       459       947 99.93  98.48 
    pct_similar_age_1m pct_similar_age_3m pct_similar_age_journal_1m 
1    99.69    99.75      90.35 
    pct_similar_age_journal_3m 
1      91.50 

El type y v ariable se separan con _, en lugar de ., sin embargo.

+0

+1 Me derrotaron. – joran

+0

¡Impresionante! Has resuelto un viejo problema para mí en el que nunca puedo volver a fundir los datos con la forma original porque las fórmulas siempre buscan una tercera variable. – Maiasaura

+0

Esto también da diferentes nombres de haber pedido, pero 1 para dar el OP un 'dcast' fijar – GSee

0

Asumiendo que su marco de datos se llama dat aquí hay una solución. Esto es un poco crudo y puede que no sea lo que buscas:

dat2 <- data.frame(matrix(unlist(lapply(1:nrow(dat), function(i) dat[i, -1])), nrow=1)) 
colnames(dat2) <- paste0(rep(dat[, 1], each=ncol(dat)-1), ".", 1:(ncol(dat)-1)) 
dat2 

Si no tiene por qué ser una trama de datos que esto podría funcionar también:

dat3 <- as.numeric(unlist(lapply(1:nrow(dat), function(i) dat[i, -1]))) 
names(dat3) <- paste0(rep(dat[, 1], each=ncol(dat)-1), ".", 1:(ncol(dat)-1)) 
dat3 
1

Aquí es una solución utilizando expand.grid para obtener los nombres.

para obtener los datos, en primer lugar, subgrupo para eliminar la primera columna que contiene los nombres. Luego, transponer y convertir a numérico.

> eg <- expand.grid(colnames(x[, -1]), x[, 1]) 
> setNames(as.numeric(t(x[, -1])), paste(eg[[2]], eg[[1]], sep=".")) 
       journal.count     journal.rank 
        13972.00      13759.00 
       journal.pct     all.count 
         98.48     754555.00 
        all.rank      all.pct 
        754043.00      99.93 
     similar_age_1m.count   similar_age_1m.rank 
        22408.00      22339.00 
      similar_age_1m.pct   similar_age_3m.count 
         99.69      56213.00 
     similar_age_3m.rank   similar_age_3m.pct 
        56074.00      99.75 
similar_age_journal_1m.count similar_age_journal_1m.rank 
         508.00      459.00 
    similar_age_journal_1m.pct similar_age_journal_3m.count 
         90.35      1035.00 
similar_age_journal_3m.rank similar_age_journal_3m.pct 
         947.00      91.50 
+0

¡Vaya! No me di cuenta de que quería un 'data.frame' – GSee

2

Ésta es otra manera:

y <- as.numeric(as.matrix(x[-1])) # flatten the data.frame 
names(y) <- as.vector(outer(x[['type']], names(x)[-1], paste, sep='.')) 
+0

funciona una vez que agregué' t (data.frame (y)) '. Respuesta elegante – Maiasaura

+0

Esto funciona si al OP no le importa si los resultados están en el mismo orden que se muestra en la pregunta. – GSee

1
#assuming your data is called "test" 
result <- as.data.frame(matrix(t(test[-1]),nrow=1),stringsAsFactors=FALSE) 
names(result) <- as.vector(t(outer(unique(test$type),names(test[-1]),paste,sep="."))) 

str(result) 
'data.frame': 1 obs. of 18 variables: 
$ journal.count    : chr "13972" 
$ journal.rank    : chr "13759" 
$ journal.pct     : chr "98.48" 
$ all.count     : chr "754555" 
$ all.rank     : chr "754043" 
$ all.pct      : chr "99.93" 
$ similar_age_1m.count  : chr "22408" 
$ similar_age_1m.rank   : chr "22339" 
$ similar_age_1m.pct   : chr "99.69" 
$ similar_age_3m.count  : chr "56213" 
$ similar_age_3m.rank   : chr "56074" 
$ similar_age_3m.pct   : chr "99.75" 
$ similar_age_journal_1m.count: chr "508" 
$ similar_age_journal_1m.rank : chr "459" 
$ similar_age_journal_1m.pct : chr "90.35" 
$ similar_age_journal_3m.count: chr "1035" 
$ similar_age_journal_3m.rank : chr "947" 
$ similar_age_journal_3m.pct : chr "91.50" 
+0

agradable, pero tiene los nombres hacia atrás. – GSee

+1

whoops ... lo arregló ahora – thelatemail

2

Suponiendo que está de acuerdo con la adición de una variable ficticia de "tiempo" para la remodelación, puede hacerlo fácilmente con la base R también. Asumiendo que su data.frame se llama:

mydf$id <- 1 
(mydfw <- reshape(mydf, direction = "wide", idvar="id", timevar="type")) 
# id count.journal rank.journal pct.journal count.all rank.all pct.all 
# 1 1   13972  13759  98.48 754555 754043 99.93 
# count.similar_age_1m rank.similar_age_1m pct.similar_age_1m 
# 1    22408    22339    99.69 
# count.similar_age_3m rank.similar_age_3m pct.similar_age_3m 
# 1    56213    56074    99.75 
# count.similar_age_journal_1m rank.similar_age_journal_1m 
# 1       508       459 
# pct.similar_age_journal_1m count.similar_age_journal_3m 
# 1      90.35       1035 
# rank.similar_age_journal_3m pct.similar_age_journal_3m 
# 1       947      91.50 

Cleanup no es tan malo tampoco, si desea cambiar el orden de las columnas.

mydfw <- mydfw[, unlist(sapply(names(mydf), grep, names(mydfw)))] 
Cuestiones relacionadas