2015-03-14 8 views
8

Próbuję obliczyć procentową zmianę zwięźle za pomocą data.table, ale mam pewne problemy ze zrozumieniem, w jaki sposób działają operacje .SD.Operacja data.table z .SD: obliczanie procentowej zmiany zwięźle

Powiedzmy mam następującą tabelę

dt = structure(list(type = c("A", "A", "A", "B", "B", "B"), Year = c(2000L, 
2005L, 2010L, 2000L, 2005L, 2010L), alpha = c(0.0364325563237498, 
0.0401968159729988, 0.0357395587861466, 0.0317236054181487, 0.0328213742235379, 
0.0294694430578336), beta = c(0.0364325563237498, 0.0401968159729988, 
0.0357395587861466, 0.0317236054181487, 0.0328213742235379, 0.0294694430578336 
)), .Names = c("type", "Year", "alpha", "beta"), row.names = c(NA, 
-6L), class = c("data.table", "data.frame")) 


> dt 
## type Year  alpha  beta 
## 1: A 2000 0.03643256 0.03643256 
## 2: A 2005 0.04019682 0.04019682 
## 3: A 2010 0.03573956 0.03573956 
## 4: B 2000 0.03172361 0.03172361 
## 5: B 2005 0.03282137 0.03282137 
## 6: B 2010 0.02946944 0.02946944 

Aby obliczyć procentową zmianę na alfa według kategorii, wpadłem na następujący kod:

dt[,change:=list(lapply(3:2,function(x)(.SD[x,alpha]/.SD[ 
(x-1),alpha]))),by=list(type)][][Year==2000,change:=NA] 

Ale coś mi mówi, ich mogli być bardziej zwięzłym sposobem na to. W szczególności, jeśli chciałoby się przeprowadzić zmianę procentową dla obu kolumn dodaje nie będzie działać

dt[,c("changeAlpha","changeBeta"):=list(lapply(3:2, 
function(x)(.SD[x]/.SD[(x-1)]))),by=list(type)][Year==2000,change:=NA][] 

więc uciekają się do:

dt[,c("changeAlpha","changeBeta"):=list(
lapply(3:2,function(x)(.SD[x,alpha]/.SD[(x-1),alpha])), 
lapply(3:2,function(x)(.SD[x,beta]/.SD[(x-1),beta]))),by=list(type)][ 
Year==2000,c("changeAlpha","changeBeta"):=list(NA,NA)][] 

##  type Year  alpha  beta  changeAlpha  changeBeta 
## 1: A 2000 0.03643256 0.03643256    NA    NA 
## 2: A 2005 0.04019682 0.04019682 1.10332131557826 1.10332131557826 
## 3: A 2010 0.03573956 0.03573956 0.889114172877617 0.889114172877617 
## 4: B 2000 0.03172361 0.03172361    NA    NA 
## 5: B 2005 0.03282137 0.03282137 1.03460416276522 1.03460416276522 
## 6: B 2010 0.02946944 0.02946944 0.897873527693412 0.897873527693412 

Ale operacje wydaje się słuszna, ale ma dużo ostrzeżeń, które zaprowadź mnie tutaj.

  • Czy moja metoda myślenia jest całkowicie błędna, czy też jest to właściwy sposób postępowania w tej operacji?

Odpowiedz

8

Można użyć funkcji shift z data.table v1.9.6 +

Określ czynność

myFunc <- function(x) x/shift(x) 

Wybierz kolumny chcesz obliczyć procent dla

cols <- c("alpha", "beta") 

Lub jeśli chcesz uruchomić to na wszystkie wartości z wyjątkiem pierwsze dwa

cols <- names(dt)[-(1:2)] 

uruchomić funkcję nad kolumnami

dt[, paste0("change", cols) := lapply(.SD, myFunc), by = type, .SDcols = cols][] 
# type Year  alpha  beta changealpha changebeta 
# 1: A 2000 0.03643256 0.03643256   NA   NA 
# 2: A 2005 0.04019682 0.04019682 1.1033213 1.1033213 
# 3: A 2010 0.03573956 0.03573956 0.8891142 0.8891142 
# 4: B 2000 0.03172361 0.03172361   NA   NA 
# 5: B 2005 0.03282137 0.03282137 1.0346042 1.0346042 
# 6: B 2010 0.02946944 0.02946944 0.8978735 0.8978735 
+0

nie mam krwawienia wersję krawędzi. Kod jest zdecydowanie bardziej zwięzły i łatwiejszy do odczytania. Jednak po zainstalowaniu najnowszej wersji data.table i uruchomieniu kodu. Mam 'object 'CisOrderedSubset' not found'. Czy masz jakąkolwiek szansę przez przypadek? – DJJ

+1

Zamknij * wszystkie * sesje R i otwórz tylko jedną i ponownie zainstaluj. –

+1

Zakończono i ponownie zainstalowano zadanie. dzięki – DJJ