2013-04-17 9 views
5

dla obiektu data.table Chciałbym zwinąć wartości niektórych pogrupowanych kolumn w jeden obiekt i wstawić wynikowe obiekty do nowej kolumny.Zwiń kolumny data.table podczas grupowania

dt <- data.table(
      c('A|A', 'B|A', 'A|A', 'B|A', 'A|B'), 
      c(0, 0, 1, 1, 0), 
      c(22.7, 1.2, 0.3, 0.4, 0.0) 
) 
setnames(dt, names(dt), c('GROUPING', 'NAME', 'VALUE')) 
dt 
# GROUPING NAME VALUE 
# 1:  A|A 0 22.7 
# 2:  B|A 0 1.2 
# 3:  A|A 1 0.3 
# 4:  B|A 1 0.4 
# 5:  A|B 0 0.0 

myślę, że w tym celu należy najpierw określić kolumnę, dla którego chcesz do grupy, więc powinienem zacząć z czymś dt[, OBJECTS := <expr>, by = GROUPING].

Niestety, nie wiem ekspresję <expr> używać tak, że wynik jest następujący:

# GROUPING OBJECTS 
# 1:  A|A <vector> 
# 2:  B|A <vector> 
# 3:  A|B <vector> 

Każdy <vector> musi zawierać wartości innych kolumn. Przykład pierwszy <vector> musi być nazwany wektor równoważne:

eg <- c(22.7, 0.3) 
names(eg) <- c('0', '1') 
# 0 1 
# 22.7 0.3 
+0

Czy próbujesz przekształcić swoją tabelę danych na format panoramiczny? – mnel

+0

twoje 'wyrażenie' powinno wyglądać jak' lista (lista (...)) ' –

+0

Ale dlaczego? Nie uważasz, że trudno jest z tym pracować? Dlaczego nie przekształcić go i mieć kolumny z wartościami odpowiadającymi '0' i' 1'? – Arun

Odpowiedz

3

myślę że jest to, czego szukasz:

dt1 <- dt[, list(list(setNames(VALUE, NAME))), by = GROUPING] 
dt1 
# GROUPING  V1 
# 1:  A|A 22.7,0.3 
# 2:  B|A 1.2,0.4 
# 3:  A|B  0 
str(dt1) 
# Classes ‘data.table’ and 'data.frame': 3 obs. of 2 variables: 
# $ GROUPING: chr "A|A" "B|A" "A|B" 
# $ V1  :List of 3 
# ..$ : Named num 22.7 0.3 
# .. ..- attr(*, "names")= chr "0" "1" 
# ..$ : Named num 1.2 0.4 
# .. ..- attr(*, "names")= chr "0" "1" 
# ..$ : Named num 0 
# .. ..- attr(*, "names")= chr "0" 
# - attr(*, ".internal.selfref")=<externalptr> 
dt1$V1 
# [[1]] 
# 0 1 
# 22.7 0.3 
# 
# [[2]] 
# 0 1 
# 1.2 0.4 
# 
# [[3]] 
# 0 
# 0 

Jak @Arun zwraca uwagę w komentarzach, w „data.table "alternatywą dla setNames w tym przypadku jest setattr(VALUE, 'names', NAME), tworząc kolejne rozwiązanie:

dt1 <- dt[, list(list(setattr(VALUE, 'names', NAME))), by = GROUPING] 
+0

Myślę, że powinieneś użyć 'setnames', a nie' setNames'. – Arun

+0

@Arun, czy możesz pokazać, jak? Nie ma starych nazw, więc nie jestem pewien, jak to zrobić, więc użyłem po prostu 'setNames' z bazy R. – A5C1D2H2I1M1N2O1R2T1

+1

Anando, oh widzę. W takim przypadku dobrze jest użyć 'setattr (VALUE, 'names', NAME)' – Arun

5

Praca wewnątrz j: Jeśli chcesz mieć wartości w kolumnie być wektorem, trzeba owinąć wyjście w list(.).

sama j wymaga połączenia do list, więc ostateczny wyraz będzie przypominać zagnieżdżony list, np:

dt[, list(allNames=list(NAME), allValues=list(VALUE)), by=GROUPING] 

# GROUPING allNames allValues 
# 1:  A|A  0,1 22.7,0.3 
# 2:  B|A  0,1 1.2,0.4 
# 3:  A|B  0   0 

Jak @Mnel zaznacza, równoważnie:

dt[, lapply(.SD, list), by=GROUPING] 

Jeśli chcesz w długiej formie, struktura twojego <expr> będzie:
list(c( list(), list(), ..., list() )) np .:

dt[, list(c(list(NAME), list(VALUE))), by=GROUPING] 

# GROUPING  V1 
# 1:  A|A  0,1 
# 2:  A|A 22.7,0.3 
# 3:  B|A  0,1 
# 4:  B|A 1.2,0.4 
# 5:  A|B  0 
# 6:  A|B  0 

lub równoważnie:

dt[, list(lapply(.SD, c)), by=GROUPING] 
Powiązane problemy