0
私は1人あたり複数の行があり、それぞれ異なる試験日に対応するデータフレームを持っています。私は今、Rcppを使って関数を書いて、最後の観測だけを含むデータフレームを得たいと思います。私は現在R(調整済みhttp://www.ats.ucla.edu/stat/r/faq/firstlast.htm)のコードを持っていますが、データフレームには20,000行と200の変数があるので、これは遅すぎます。最後の観測結果のみを含むデータフレームを返します。 Rcppを使用している患者
# function
last.obs <- function(id,data){
args <- as.list(match.call())[-1]
tmp <- data
tmp$id <- eval(args$id,data)
uni.id <- unique(tmp$id)
last <- c()
for (i in unique(uni.id)){
temp<-tmp[which(tmp$id==i),]
if (dim(temp)[1] > 1){
last.temp<-temp[dim(temp)[1],]
}else{last.temp<-temp}
last<-rbind(last, last.temp)
}
last
}
# create sample data
data <- data.frame("id"=sort(sample(letters[1:3],20,T)),"x1"=rnorm(20),
"x2"=rnorm(20), "x3"=sample(c("Drug","Treatment"),20,T))
# example of function
last.obs(id,data)
これをC++で記述しようとしましたが、関数全体を記述するのに十分ではありません。最後の行だけを除いてデータをサブセット化し、rbind
のC++に相当するものを見つけることには問題があります。私は本当にC++でうまく行きたいと思っています。だから誰かが私に助けてくれたら本当に感謝しています。これは私が今まで持っていたコードです(コードは駄目です)。最後の観察のために
> df[!duplicated(df$A), ]
A B
1 1 a
2 2 a
4 3 a
:最初の観察のため
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export("lastobs")]]
Rcpp::DataFrame lastobs(Rcpp::CharacterVector id, Rcpp::DataFrame data){
int unid = id.size();
Rcpp::CharacterVector id_data = data["id"];
Rcpp::CharacterVector id_loop;
Rcpp::NumericVector matchid;
Rcpp::DataFrame lastobs;
for(int i=0; i<unid;i++){
id_loop = id(i);
matchid = Rcpp::match(id_data,id_loop);
// I do not know I can best proceed from here
}
return lastobs;
}
0.05秒、私はこれはC++でそれを書くよりも優れていると思います。ありがとう!なぜこれがずっと速いのか分かりますか?私はループではRが遅いことを知っているので、これは問題の一部であることは既に知っていましたが、私はこのコードがこれほど早いと期待していませんでした。 –
何が問題になっているのか分かりませんが、ヘルプドキュメントを読んでいると、重複した(x、fromLast = TRUE)と同等ですが、rev(dupl(rev(x))より速い)だから、0.04秒にまで下げることができます。 –
'df [!duplicated(df $ A、fromLast = TRUE)]を使って、あなたは正しいでしょう。 24665の行と275の変数を持つデータフレームの場合、0.03秒ですが、これはちょっと狂っています。 –