我有一个数据框,每个人有多行,这些对应于不同的考试日期。我现在想用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;
}
答案 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