2017-12-20 6 views
-3

ich komme noch in dem Griff, wie r besten Daten zu manipulieren mit ...r breite Daten an widish und lange

Wenn möglich, mag mich, dies zu tun mit tidyr oder dplyr packages/Funktionen.

Ich habe einige Daten in wie diese kommen:

cost <- tibble(
    v1=c('some text1','group1','name','date',c(runif(3),NA,NA,NA)), 
    v2=c('some text1','group1','name','value',c(runif(3),NA,NA,NA)), 
    v3=c('some text2','group1','name2','date',c(runif(4),NA,NA)), 
    v4=c('some text2','group1','name2','value',c(runif(4),NA,NA)), 
    v5=c('some text3','group2','name3','date',runif(6)), 
    v6=c('some text3','group2','name3','value',runif(6)) 
) 
cost[] <- lapply(cost, factor) 
> glimpse(cost) 
Observations: 10 
Variables: 6 
$ v1 <fctr> some text1, group1, name, date, 0.924267573514953, 0.203127129469067, 0.0484973937273026, NA, NA, NA 
$ v2 <fctr> some text1, group1, name, value, 0.712983385194093, 0.994925277773291, 0.0975768479984254, NA, NA, NA 
$ v3 <fctr> some text2, group1, name2, date, 0.188781834673136, 0.859566977713257, 0.739685433451086, 0.2719707184... 
$ v4 <fctr> some text2, group1, name2, value, 0.416961463401094, 0.558401603251696, 0.334375116974115, 0.195782373... 
$ v5 <fctr> some text3, group2, name3, date, 0.857840840239078, 0.545017473166808, 0.209725016728044, 0.5044016360... 
$ v6 <fctr> some text3, group2, name3, value, 0.551554219797254, 0.529705551918596, 0.258927160175517, 0.517376250... 

Ich möchte es länger machen, und breiter. Das sind die ersten 3 Zeilen, die in 3 Spalten verschoben werden und deren Werte entlang der Daten für diesen Namen dupliziert werden. Ich würde auch die fehlende Werte fallen mag, sie NA nicht sein mögen, es sieht aus wie sie nur leer sind (diese waren read.csv in aus CSV-Datei)

> cost <- tibble(
    name=c('name', 'name','name'), 
    desc=c('some text1', 'some text1', 'some text1'), 
    group=c('group2', 'group2', 'group2'), 
    date=c('dd-mm-yy', 'dd-mm-yy', 'dd-mm-yy'), 
    value=c(runif(1), runif(1), runif(1)) 
    ) 
> cost 
# A tibble: 3 x 5 
    name  desc group  date  value 
    <chr>  <chr> <chr> <chr>  <dbl> 
1 name some text1 group2 dd-mm-yy 0.04565986 
2 name some text1 group2 dd-mm-yy 0.82689013 
3 name some text1 group2 dd-mm-yy 0.67433167 
+1

Can u die erwartete Ausgabe zeigen? Du hast die ersten 3 Zeilen gesagt, die auch 'sometext' enthalten. Was ist 'desc'? – akrun

+0

Meinst du 't (kosten)'? – Prem

+0

Ich habe die Beispielausgabe hinzugefügt. Es gibt einige Feinheiten in diesem Problem. Nein, ich meine nicht "t (kosten)", hoffentlich machen die zusätzlichen Daten das klar? – Hedgehog

Antwort

1

Ich glaube, ich Ihr gewünschtes Ergebnis zu verstehen. Wenn ich jedoch falsch liege, bitte modelliere, was du eigentlich aus diesen Daten herausholen willst.

Dazu verwende ich mehrere Funktionen von tidyr.

Zuerst werde ich neue Spaltenbeschriftungen erstellen, die die vier Zeilen der Kopfzeileninformationen, die Sie haben, reduzieren. Im Grunde genommen nehme ich die ersten vier Zeilen, die jeweils zu einer einzigen Zeichenkette zusammengefasst werden (mit einem Drei-Unterstrich-Abstandhalter, der in Ihren tatsächlichen Daten wahrscheinlich nicht vorkommt), und wandle dann den data.frame in einen Zeichenvektor um.

myColNames <- 
    cost[1:4,] %>% 
    summarise_all(paste, collapse = "___") %>% 
    c %>% 
    unlist 

Erzeugt

        v1         v2         v3 
    "some text1___group1___name___date" "some text1___group1___name___value" "some text2___group1___name2___date" 
            v4         v5         v6 
"some text2___group1___name2___value" "some text3___group2___name3___date" "some text3___group2___name3___value" 

Als nächstes kann ich die Zeilen entferne ich, nur verwendet, um die Spaltennamen zu machen und die Namen einfügen Spalten statt (setNames verwenden). Als Nächstes fügte ich einen Index hinzu, um die Daten in einer Zeile miteinander zu verknüpfen (wenn sie aus demselben Header stammt). Dann kann ich gather den Datensatz in ein langes Format und separate die Spaltenüberschriften, die ich in ihre Komponenten erstellt habe. Schließlich kann ich spread die Datums- und Werteinträge in separate Spalten (auf die gleiche Zeile wegen der rowIdx abgestimmt) und die fehlenden Beobachtungen herausfiltern.

cost[-(1:4), ] %>% 
    ## This step is only necessary if the data 
    ## were imported as factors instead of as character 
    mutate_all(funs(as.character)) %>% 
    setNames(myColNames) %>% 
    mutate(rowIdx = 1:n()) %>% 
    gather(key, tempVal, -rowIdx) %>% 
    separate(key, c("Text", "Group", "Name", "toSpread"), sep = "___") %>% 
    spread(toSpread, tempVal) %>% 
    filter(!is.na(date)) 

kehrt

rowIdx  Text Group Name    date    value 
    <int>  <chr> <chr> <chr>    <chr>    <chr> 
1  1 some text1 group1 name 0.601032865699381 0.320803644834086 
2  1 some text2 group1 name2 0.755003974540159 0.724728998960927 
3  1 some text3 group2 name3 0.782037091907114 0.642663416918367 
4  2 some text1 group1 name 0.0365895153954625 0.131514045642689 
5  2 some text2 group1 name2 0.0913304232526571 0.198074621148407 
6  2 some text3 group2 name3 0.690302846953273 0.915490478742868 
7  3 some text1 group1 name 0.912119234679267 0.474282702198252 
8  3 some text2 group1 name2 0.909885906847194 0.125321796629578 
9  3 some text3 group2 name3 0.883244396885857 0.850464047864079 
10  4 some text2 group1 name2 0.894993636989966 0.443535323021933 
11  4 some text3 group2 name3 0.674304561689496 0.823389955097809 
12  5 some text3 group2 name3 0.700140621513128 0.458009321708232 
13  6 some text3 group2 name3 0.19869831786491 0.00457167089916766 
+0

Wow. Das war überhaupt nicht offensichtlich. Vielen Dank. – Hedgehog

+0

'read.csv' macht dies noch subtiler .... indem man alles in einen Faktor umwandelt - das verheert den Inhalt der' value' Spalten im obigen Code. – Hedgehog

+0

Ja, wenn Sie Daten verwenden, die sich grundlegend von den angezeigten Beispieldaten unterscheiden, treten Probleme auf. Meine Vermutung ist, dass zwei der Spalten in Ihrem Dataset identische Werte für die Zeilen haben, die Sie einfügen. Sie sollten in der Lage sein, dies zu beheben, indem Sie am Ende der Zeichenfolge einen eindeutigen Wert hinzufügen (z. B. das Trennzeichen mit drei Unterstrichen, gefolgt von einem Index). Stellen Sie nur sicher, dass entweder die Daten in diesen Spalten das Gleiche bedeuten oder dass Sie mit dem Index herausfinden, was es bedeutet. Verwenden Sie 'stringsAsFactors = FALSE' in' read.csv' (oder 'read_csv' von' readr'), um Faktoren zu vermeiden –