2013-08-28 9 views
5

Mam dane (nazwijmy to mydata) z następującą ramką danych.Jak pracować z portfelem zamówień z funkcją R "by"?

datetime|side(0=Bid,1=Ask)| distance(1:best price, 2: 2nd best, etc.)| price 
2008/01/28,09:11:28.000,0,1,1.6066 
2008/01/28,09:11:28.000,0,2,1.6065 
2008/01/28,09:11:28.000,0,3,1.6064 
2008/01/28,09:11:28.000,0,4,1.6063 
2008/01/28,09:11:28.000,0,5,1.6062 

2008/01/28,09:11:28.000,1,1,1.6067 
2008/01/28,09:11:28.000,1,2,1.6068 
2008/01/28,09:11:28.000,1,3,1.6069 
2008/01/28,09:11:28.000,1,4,1.6070 
2008/01/28,09:11:28.000,1,5,1.6071 

Chcę obliczyć minAsk-maxBid, w tym przypadku = 1.6067-1.6066. Chcę to zrobić dla wszystkich moich danych. Myślałam używając „za”, ale nawet za pomocą tego prostego kodu:

by(mydata,mydata$datetime, min(mydata$price)) 

znaleźć tylko cenę minimalną w każdym bloku pojawia się następujący błąd: Błąd w Fun (X [[1L]] ...): nie można znaleźć funkcji "FUN"

Każdy pomysł, jak to zrobić? Czy powinienem użyć innej funkcji: ddply?

+1

Jeśli masz „odległość” tak naprawdę nie potrzebują Min/Max; możesz po prostu ustawić tylko opcję "distance == 1". W rzeczywistości, jeśli twoje dane są czyste, a spread nigdy nie jest przekroczony, możesz po prostu wziąć "abs" różnicy cen, gdzie odległość == 1 za każdym razem. – GSee

+0

Otrzymasz najlepsze odpowiedzi, jeśli sprawisz, że twoje dane będą odtwarzalne. W takim przypadku, jeśli właśnie dostarczysz wynik "dput (mydata)" w swoim pytaniu, uzyskasz lepsze odpowiedzi. Zauważ, że to co pokazałeś ma osobne kolumny dla daty i czasu, ale naprawdę powinieneś użyć jednej kolumny datetime (prawdopodobnie POSIXct). – GSee

+0

@ GSee- Moje dane były w kolumnach. Pójdę z rozwiązaniem w drugiej odpowiedzi, ponieważ ustawienie sub w dużych danych nie jest wydajne. Dzięki za uwagi na temat zamieszczania dodatkowych informacji, jestem tu nowy i zrobię to od niedawna. – mitra

Odpowiedz

3

dajesz by niewłaściwym wymaganych nakładów. Trzeba coś takiego:

by(mydata,mydata$datetime, function(x) min(x$price)) 
#mydata$datetime: 2008/01/28,09:11:28.000 
#[1] 1.6062 

Zobacz ?by - co jest najbardziej podstawowym by bierze wejść ...

by(data, INDICES, FUN) 

Funkcja FUN jest stosowany do całego podzbioru data.frame określonym jako data. To znaczy. jeśli użyjesz identity jako funkcji FUN, każdy podzbiór zdefiniowany przez INDICES zostanie zwrócony. Spróbuj:

by(mydata,mydata$datetime, identity) 

Dlatego nie można po prostu poprosić o min(mydata$price) bezpośrednio, trzeba poprosić o min zmiennej w podgrupie price. Można napisać mój oryginalny odpowiedź longhand jako ...

by(mydata,mydata$datetime, function(subdataset) min(subdataset$price)) 

Aby rozwinąć to do pełnego problemu, można zrobić coś takiego:

by(
    mydata, 
    mydata$datetime, 
    function(x) min(x$price[x$side==1]) - max(x$price[x$side==0]) 
) 
#mydata$datetime: 2008/01/28,09:11:28.000 
#[1] 1e-04 

na przyszłość, jest bardzo podobna do teorii sposób działania pakietu data.table przy jego argumencie by= i jego kodzie .SD (pod-danych). data.table odpowiedź w tym przypadku jest jeszcze prostsze mimo:

mydt <- as.data.table(mydata) 

mydt[,min(price[side==1]) - max(price[side==0]),by=datetime] 
#     datetime V1 
#1: 2008/01/28,09:11:28.000 1e-04 

mydt[,list(minmax=min(price[side==1]) - max(price[side==0])),by=datetime] 
#     datetime minmax 
#1: 2008/01/28,09:11:28.000 1e-04 
+2

Podejście "data.table" nie wymaga '.SD'.'mydt [, min (price), by = datetime]' jest wystarczający i preferowany – mnel

+0

@mnel - cholera, masz rację - to osłabia moją analogię pomiędzy 'by' i' .SD' chociaż ;-) – thelatemail

+0

wspaniałych punktów, Użyłem data.table, nie miałem pojęcia, że ​​jest inaczej. dlaczego to nie działa: mydt [, (min (cena [strona == 1]) - max (cena [strona == 0])), by = datetime] – mitra

4

Spróbuj

by(mydata,mydata$datetime, function(d)with(d, min(price[side==1])-max(price[side==0])))