6

何百万行もの大きなデータ フレームがあります。時系列データです。例えば:

dates <- c(1,2,3)
purchase_price <- c(5,2,1)
income <- c(2,2,2)
df <- data.frame(dates=dates,price=purchase_price,income=income)

「十分なお金がある場合は購入し、そうでない場合はお金を節約する」などのルールを使用して、毎日の支出を示す新しい列を作成したいと考えています。

私は現在、データフレームの各行をループして、現在の合計金額を追跡しています。ただし、これは大規模なデータセットでは永遠にかかります。私が知る限り、この実行中の変数を追跡する必要があるため、ベクトル演算を行うことはできません。

私がやっているforループの中で:

balance = balance + row$income
buy_amt = min(balance,row$price)
balance = balance - buy_amt

より速い解決策はありますか?

ありがとう!

4

2 に答える 2

4

ループで簡単に表現できる問題については、Rcpp が適切なソリューションであるとますます確信するようになりました。比較的簡単に習得でき、loop-y アルゴリズムを非常に自然に表現できます。

Rcppを使用した問題の解決策は次のとおりです。

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
List purchaseWhenPossible(NumericVector date, NumericVector income, 
                          NumericVector price, double init_balance = 0) {  
  int n = date.length();
  NumericVector balance(n);
  LogicalVector buy(n);

  for (int i = 0; i < n; ++i) {
    balance[i] = ((i == 0) ? init_balance : balance[i - 1]) + income;

    // Buy it if you can afford it
    if (balance[i] >= price[i]) {
      buy[i] = true;
      balance[i] -= price[i];
    } else {
      buy[i] = false;
    }

  }

  return List::create(_["buy"] = buy, _["balance"] = balance);
}

/*** R

# Copying input data from Ricardo
df <- data.frame(
  dates = 1:6,
  income = rep(2, 6),
  price = c(5, 2, 3, 5, 2, 1)
)

out <- purchaseWhenPossible(df$dates, df$income, df$price, 3)
df$balance <- out$balance
df$buy <- out$buy

*/

実行するには、 という名前のファイルに保存してからpurchase.cpp実行しますRcpp::sourceCpp("purchase.cpp")

C++ は非常に高速であるため、非常に高速になりますが、正式なベンチマークは行っていません。

于 2013-10-28T15:03:27.510 に答える