2017-09-25 5 views
2

私は、時系列データセットを持っています。関数を使用してデータフレームを更新して連続最良値を見つける

Time Price 
15:30:01 NA 
15:30:02 NA 
15:30:03 36 
15:30:04 38 
15:30:05 37.5 
15:30:06 NA 
15:30:07 NA 
15:30:08 37 
15:30:09 37.8 
15:30:10 39 
15:30:11 40 
15:30:12 38.5 
15:30:13 38 
15:30:14 38 

私はこのような最高の価格を返す関数を書くことを探しています:

Time Price Best Price 
15:30:01 NA 36 
15:30:02 NA 36 
15:30:03 36 36 
15:30:04 38 38 
15:30:05 37.5 38 
15:30:06 NA 38 
15:30:07 NA 38 
15:30:08 37 38 
15:30:09 37.8 38 
15:30:10 39 39 
15:30:11 40 40 
15:30:12 38.5 40 
15:30:13 38 40 
15:30:14 38 40 

私はna.omit(価格を経由して私のprice2を開始します

bbo <- function(price1, price2) { 
    currbestprice <- price2 
    newbestprice <- ifelse(price1 >= currbestprice, price1, currbestprice) 
    currbestprice <- newbestprice 
    return(currbestprice) 
} 

を試してみました)[1]を使用して最初の非NA値を取得します。私は、常に最も最近のベストプライスを保持するために継続的に更新されるcurrbestpriceを希望します。 Price1は単なる価格系列です。

しかし、私はこれをテストする場合:

p1 <- c(NA,NA,36,38,37.5,NA,NA,37,37.8,39,40,38.5,38,38) 
p2 <- 36 

bbo(p1,p2)戻り

NA NA 36.0 38.0 37.5 NA NA 37.0 37.8 39.0 40.0 38.5 38.0 38.0 

私のcurrbestpriceを更新していないようです。私は立ち往生して助けていただければ幸いです。

+0

あなたは0でNAを置き換えることができますか? –

+0

もちろん、それでも最高の価格を返すという大きな問題は解決しません。 NAを0に置き換えた場合、36.0 36.0 36.0 38.0 37.5 36.0 36.0 37.0 37.8 39.0 40.0 38.5 38.0 38.0の代わりに38 36 36 38 38 38 38 38 39 40 40 40 40 –

+0

最初の2つの値は「NA」または0第3の価値まで「価格」がないからです。 「ave(1:nrow(df)、1:nrow(df)、FUN = function(x)max(df $ Price [1:x]、na.rm = TRUE)」のような何か? –

答えて

3

cummax -functionのもう一つの基本Rオプション:

# create a new column 'BestPrice' 
df$BestPrice <- df$Price 

# replace the first NA with the first non-NA value 
df$BestPrice[is.na(df$BestPrice)][1] <- df$BestPrice[!is.na(df$BestPrice)][1] 

# relace the remaining NA's with zero 
df$BestPrice[is.na(df$BestPrice)] <- 0 

# use 'cummax' to replace the values with the best price untill that point 
df$BestPrice <- cummax(df$BestPrice) 

これは:

> df 
     Time Price BestPrice 
1 15:30:01 NA  36 
2 15:30:02 NA  36 
3 15:30:03 36.0  36 
4 15:30:04 38.0  38 
5 15:30:05 37.5  38 
6 15:30:06 NA  38 
7 15:30:07 NA  38 
8 15:30:08 37.0  38 
9 15:30:09 37.8  38 
10 15:30:10 39.0  39 
11 15:30:11 40.0  40 
12 15:30:12 38.5  40 
13 15:30:13 38.0  40 
14 15:30:14 38.0  40 

別のオプションは、cummaxとの組み合わせでzoo -packageからfromLast = TRUE -parameterでna.locfを使用することです:

library(zoo) 
df$BestPrice <- na.locf(df$Price, fromLast = TRUE) 
df$BestPrice <- cummax(df$BestPrice) 
+1

おかげであなたの提案をたくさんありました。ループを避けるために探していた、これは完全にそれを行います。 T –

1

あなたはこの試みることができる:

# simulate some data 
data = data.frame(
    time = 1:100, 
    price = rpois(1:100, lambda = 10) 
); 

# add some random NA values to it, as in your data 
na_idxs = sample(x = 1:100, size = 30); 
data[na_idxs, 2] = NA; 

# initialise a value we'll update storing the max price 
c_max = 0; 

# the vector containing the best prices 
best_price = list(); 

# for every price 
for(i in 1:length(x = data$price)){ 

    # if the current price is NA 
    if(is.na(x = data$price[i])){ 
    # don't update c_max 
    } 
    # if the current value exceeds c_max 
    else if(data$price[i] > c_max){ 
    # update c_max to this value 
    c_max = data$price[i]; 
    } 
    # given the above is mutually exclusive, the current price must be less than c_max 
    # so don't update 
    else { 
    # don't update c_max 
    } 

    # add c_max to best_price 
    best_price[[i]] = c_max; 
} 

# add best_price to data by adding the column to the end 
data = cbind(data, best_price = unlist(x = best_price)); 

# output the data 

    time price best_price 
1  1  8   8 
2  2 13   13 
3  3  7   13 
4  4  7   13 
5  5  6   13 
6  6 14   14 
7  7  6   14 
8  8 NA   14 
9  9  7   14 
10 10 NA   14 
11 11  9   14 
12 12 11   14 
13 13 16   16 
14 14 14   16 
15 15 14   16 
16 16 NA   16 
17 17  4   16 
18 18 11   16 
+0

RはCではなく、大きなオブジェクトの場合は、成長するオブジェクト(例えば、 'best_price')は非常に高価になる可能性がありますので避けてください。また、Rには最後に ';'は必要ありません。 –

+0

ローマに感謝、私はそれを調整します。セミコロンについては申し訳ありません! –

1

をあなたが(0であることをNAと仮定して)これを試すことができ

df <- read.table(text = " 
      15:30:01 NA 
      15:30:02 NA 
      15:30:03 36 
      15:30:04 38 
      15:30:05 37.5 
      15:30:06 NA 
      15:30:07 NA 
      15:30:08 37 
      15:30:09 37.8 
      15:30:10 39 
      15:30:11 40 
      15:30:12 38.5 
      15:30:13 38 
      15:30:14 38") 

colnames(df) <- c("Time", "Price") 

df[which(is.na(df$Price)),"Price"] <- 0 
Bestprice = df[which(df$Price > 0)[1],"Price"] 

for(i in 1:nrow(df)){ 

    if(Bestprice < df$Price[i]){ 
    df$BestPrice[i] <- df$Price[i] 
    Bestprice <- df$Price[i] 
    } else{ 
    df$BestPrice[i] <- Bestprice 
    } 
} 

> df 
Time Price BestPrice 
1 15:30:01 0.0  36 
2 15:30:02 0.0  36 
3 15:30:03 36.0  36 
4 15:30:04 38.0  38 
5 15:30:05 37.5  38 
6 15:30:06 0.0  38 
7 15:30:07 0.0  38 
8 15:30:08 37.0  38 
9 15:30:09 37.8  38 
10 15:30:10 39.0  39 
11 15:30:11 40.0  40 
12 15:30:12 38.5  40 
13 15:30:13 38.0  40 
14 15:30:14 38.0  40 
+0

ありがとうHardik、それも働いた –

関連する問題