2015-08-03 9 views
11

Mam dataframe ze struktury panelu: 2 obserwacji dla każdej jednostki z dwóch lat:Jak kontrolować nazwy nowych zmiennych po rozprzestrzenianiu tidyr?

library(tidyr) 
mydf <- data.frame(
    id = rep(1:3, rep(2,3)), 
    year = rep(c(2012, 2013), 3), 
    value = runif(6) 
) 
mydf 
# id year  value 
#1 1 2012 0.09668064 
#2 1 2013 0.62739399 
#3 2 2012 0.45618433 
#4 2 2013 0.60347152 
#5 3 2012 0.84537624 
#6 3 2013 0.33466030 

chciałbym przekształcić te dane do formatu szerokiego które można łatwo zrobić z tidyr::spread. Ponieważ wartości zmiennej year są liczbami, nazwy moich nowych zmiennych również stają się liczbami, co sprawia, że ​​ich dalsze użycie jest trudniejsze.

spread(mydf, year, value) 
# id  2012  2013 
#1 1 0.09668064 0.6273940 
#2 2 0.45618433 0.6034715 
#3 3 0.84537624 0.3346603 

Wiem, że mogę łatwo zmienić nazwę kolumny. Jednakże, jeśli chciałbym przekształcić w łańcuchu z innymi operacjami, staje się niewygodne. Na przykład. poniższy wiersz oczywiście nie ma sensu.

library(dplyr) 
mydf %>% spread(year, value) %>% filter(2012 > 0.5) 

Poniższe działa, ale nie jest to zwięzła:

tmp <- spread(mydf, year, value) 
names(tmp) <- c("id", "y2012", "y2013") 
filter(tmp, y2012 > 0.5) 

Każdy pomysł, w jaki sposób mogę zmienić nowe nazwy zmiennych wewnątrz spread?

Odpowiedz

11

Można użyć backticks nazw kolumn zaczynające się od cyfr i filter powinien działać zgodnie z oczekiwaniami

mydf %>% 
     spread(year, value) %>% 
     filter(`2012` > 0.5) 
    # id  2012  2013 
    #1 3 0.8453762 0.3346603 

Albo inna opcja byłaby korzystania unite dołączyć dwie kolumny do jednego columnn po utworzeniu drugiej kolumnie „YEAR1” z ciągiem "y".

mydf %>% 
    mutate(year1='y') %>% 
    unite(yearN, year1, year) %>% 
    spread(yearN, value) %>% 
    filter(y_2012 > 0.5) 
# id y_2012 y_2013 
#1 3 0.8453762 0.3346603 

Nawet możemy zmienić 'Year' kolumnę wewnątrz mutate za pomocą paste

mydf %>% 
    mutate(year=paste('y', year, sep="_")) %>% 
    spread(year, value) %>% 
    filter(y_2012 > 0.5) 
2

Inną opcją jest użycie funkcji setNames() jako następną rzeczą w rurze:

mydf %>% 
    spread(mydf, year, value) %>% 
    setNames(c("id", "y2012", "y2013")) %>% 
    filter(y2012 > 0.5) 

Jedyny problem z używaniem setNames polega na tym, że musisz dokładnie wiedzieć, jakie będą kolumny po ich spread(). Przez większość czasu nie stanowi to problemu, szczególnie jeśli pracujesz częściowo interaktywnie.

Ale jeśli brakuje ci pary klucz/wartość w oryginalnych danych, istnieje szansa, że ​​nie pojawi się ona jako kolumna, a możesz nazwać kolumny nieprawidłowo, nawet o tym nie wiedząc. Zgoda, setNames() spowoduje zgłoszenie błędu, jeśli liczba nazw nie zgadza się z liczbą kolumn, więc masz wbudowaną kontrolę błędów.

Mimo to wygoda korzystania z setNames() przewyższa ryzyko więcej często nie dla mnie.

Powiązane problemy