2016-07-28 12 views
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
> df = data.frame(A = c(1,2,2,3,3,3), B = c('a','a','b','a','b','c')) 

    A B 
1 1 a 
2 2 a 
3 2 b 
4 3 a 
5 3 b 
6 3 c 

> df[rev(!duplicated(rev(df$A))), ] 

    A B 
1 1 a 
3 2 b 
6 3 c 
+0

0.05秒、私はこれはC++でそれを書くよりも優れていると思います。ありがとう!なぜこれがずっと速いのか分かりますか?私はループではRが遅いことを知っているので、これは問題の一部であることは既に知っていましたが、私はこのコードがこれほど早いと期待していませんでした。 –

+0

何が問題になっているのか分かりませんが、ヘルプドキュメントを読んでいると、重複した(x、fromLast = TRUE)と同等ですが、rev(dupl(rev(x))より速い)だから、0.04秒にまで下げることができます。 –

+0

'df [!duplicated(df $ A、fromLast = TRUE)]を使って、あなたは正しいでしょう。 24665の行と275の変数を持つデータフレームの場合、0.03秒ですが、これはちょっと狂っています。 –

関連する問題