2013-02-22 16 views
7

Potrzebuję zmienić organizację danych z pliku csv zawierającego głównie powtarzające się dane. Mam dane importowane do R w dataframe ale mam problemy z następujących czynności:Reorganizacja danych z 3 wierszy do 1

ID Language Author Keyword 
12 eng  Rob  COLOR=Red 
12 eng  Rob  SIZE=Large 
12 eng  Rob  DD=1 
15 eng  John  COLOR=Red 
15 eng  John  SIZE=Medium 
15 eng  John  DD=2 

Co muszę zrobić, to przekształcić to w jednym rzędzie z każdego słowa kluczowego w oddzielnej kolumnie

ID Language Author COLOR SIZE  DD 
12 eng  Rob  Red Large  1 

Jakieś pomysły?

Odpowiedz

7

Korzystanie pakiet reshape2 jest prosta:

Z tt zdefiniowane jak w Gary's answer

library("reshape2") 

tt <- cbind(tt, colsplit(tt$Keyword, "=", c("Name", "Value"))) 
tt_new <- dcast(tt, ID + Language + Author ~ Name, value.var="Value") 

co daje

> tt_new 
    ID Language Author COLOR DD SIZE 
1 12  eng Rob Red 1 Large 
2 15  eng John Red 2 Medium 
+0

Mogę to uruchomić, ale po uruchomieniu dcast() pojawia się komunikat o błędzie: Brak funkcji agregacji: domyślna długość. Następnie otrzymuję 1 w każdej z nowych zmiennych. Wydaje mi się, że w prawdziwym zestawie danych musi istnieć coś, co nie jest poprawne, ponieważ działa poprawnie na tym uproszczonym zbiorze danych. Jakieś pomysły? – Ray

+0

Wygląda na to, że mam gdzieś nierówne numery. Musisz dowiedzieć się, jak znaleźć identyfikator z więcej niż 3 rzędami i wyczyścić go. – Ray

+0

Otrzymasz to ostrzeżenie, jeśli istnieje kombinacja "ID", "Język", "Autor" i "Nazwa", która pojawia się więcej niż raz. Możesz określić, który to jest/które są, szukając wartości innej niż 1 w wyniku (zasadniczo, gdy istnieje wiele wartości dla kombinacji, przekształć je w jedną wartość i domyślnie, że w jakiś sposób po prostu liczy ile tam jest). –

6

Korzystanie plyr ans strsplit można zrobić coś takiego:

library(plyr) 
res <- ddply(dat,.(ID,Language,Author),function(x){ 
     unlist(sapply(strsplit(x$Keyword,'='),'[',2)) 
}) 

colnames(res)[4:6] <- c('COLOR','SIZE','DD') 

ID Language Author COLOR SIZE DD 
1 12  eng Rob Red Large 1 
2 15  eng John Red Medium 2 

Edit: o to uogólnienie, że adresy @ Briana dotyczą:

res <- ddply(dat,.(ID,Language,Author), function(x){ 
      kv <- strsplit(x$Keyword, '=') 
      setNames(sapply(kv, `[`, 2), 
         sapply(kv, `[`, 1)) }) 
+0

tak, że jest ładniejsza ;-) –

+2

Jako punkt ostrożnością, to robi Załóżmy, że słowa kluczowe mają zawsze "KOLOR", "ROZMIAR" i "DD" i zawsze w tej kolejności. Jeśli to założenie jest prawdziwe, działa to dobrze. –

+0

@flodel dzięki za elegancką edycję. – agstudy

1

Spróbuj używając reshape2:

tt <- read.table(header=T,text='ID Language Author Keyword 
12 eng  Rob  COLOR=Red 
12 eng  Rob  SIZE=Large 
12 eng  Rob  DD=1 
15 eng  John  COLOR=Red 
15 eng  John  SIZE=Medium 
15 eng  John  DD=2') 

tt$Keyword <- as.character(tt$Keyword) 

tt <- transform(tt, key_val = lapply(tt$Keyword,function(x) strsplit(x,'=')[[1]][2]), 
key_var = lapply(tt$Keyword,function(x) strsplit(x,'=')[[1]][1])) 

tt_new <- dcast (tt, ID + Language + Author ~ key_var, value.var='key_val') 
+0

Czy jesteś pewien, że to działa ..? – agstudy

+0

Twoje 'lapply's powinny być' sapply's i potrzebujesz 'value.var =" key_val "' w twoim wywołaniu 'dcast'. –

+0

Nie uświadomiłem sobie, że wartość "value.var" wymaga var w cudzysłowach, więc spowodowało to błąd. Opuściłem to, ale 'dcast' odgadł odpowiednią zmienną odpowiednio w tym przypadku. Dzięki. –

Powiązane problemy