只返回最后一次观察到的数据帧。患者,使用Rcpp

时间:2016-07-28 18:54:15

标签: c++ r rcpp

我有一个数据框,每个人有多行,这些对应于不同的考试日期。我现在想用Rcpp编写一个函数,这样我得到的数据帧只包含最后的观察结果。我目前在R中有一个代码(从http://www.ats.ucla.edu/stat/r/faq/firstlast.htm调整),但由于数据帧有超过20 000行和200个变量,这太慢了。

# 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 ++中变得更好,所以如果有人可以帮助我,我真的很感激。这是我到目前为止的代码(对于糟糕的代码感到抱歉)。

#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;
}

1 个答案:

答案 0 :(得分: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[!duplicated(df$A), ]
  A B
1 1 a
2 2 a
4 3 a

最后一次观察:

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

  A B
1 1 a
3 2 b
6 3 c