在r中修改数据帧的有效方法

时间:2013-07-08 19:58:33

标签: r

我有一个类似以下的数据框(但更大)

df<-data.frame(Claim=c("117","249","117","117","249","652"),ValuationDate=c("01/05/1965","01/05/1980","01/10/1965","01/20/1965","01/30/1980","01/10/1990"))

df
  Claim ValuationDate
1   117    01/05/1965
2   249    01/05/1980
3   117    01/10/1965
4   117    01/20/1965
5   249    01/30/1980
6   652    01/10/1990

我想添加一个列“ValuationNumber”,每个索赔的最早估值日期为1,并且每个后续估值日期(每个索赔)增加1。例如。第5行的ValuationNumber为2,因为第5行描述了日期为01/30/1980的权利要求249,这是第二次评估权利要求249。 df的完整输出看起来像

df
  Claim ValuationDate  ValuationNumber
1   117    01/05/1965   1
2   249    01/05/1980   1
3   117    01/10/1965   2
4   117    01/20/1965   3
5   249    01/30/1980   2
6   652    01/10/1990   1

添加我需要的列的有效方法是什么?

5 个答案:

答案 0 :(得分:2)

这与this data.table问题非常相似:

library(data.table)
dt = data.table(df)

dt[, ValuationNumber := 1:.N, by = Claim]
dt
#   Claim ValuationDate ValuationNumber
#1:   117    01/05/1965               1
#2:   249    01/05/1980               1
#3:   117    01/10/1965               2
#4:   117    01/20/1965               3
#5:   249    01/30/1980               2
#6:   652    01/10/1990               1

答案 1 :(得分:2)

R Base解决方案

> transform(df, ValuationNumber=ave(rep(1,nrow(df)), df$Claim, FUN=seq))
  Claim ValuationDate ValuationNumber
1   117    01/05/1965               1
2   249    01/05/1980               1
3   117    01/10/1965               2
4   117    01/20/1965               3
5   249    01/30/1980               2
6   652    01/10/1990               1

答案 2 :(得分:1)

使用plyr

ddply(df, "Claim", function(d) { d$ValuationNumber <- seq_along(d$Claim); d})

这也会破坏订单。

答案 3 :(得分:0)

您可以通过按日期拆分,添加新列以及重建df来执行此操作:

out <- lapply(split(df,df$Claim), function(x) {
    ValuationNumber <- 1:dim(x)[1]
    cbind(x,ValuationNumber)
})
dfout <- do.call(rbind, out)

并且可选择按日期排序(但最好先转换为日期类,以便按实际时间顺序排序):

dfout[order(dfout$ValuationDate),]

结果:

      Claim ValuationDate ValuationNumber
117.1   117    01/05/1965               1
249.2   249    01/05/1980               1
117.3   117    01/10/1965               2
652     652    01/10/1990               1
117.4   117    01/20/1965               3
249.5   249    01/30/1980               2

答案 4 :(得分:0)

如果这是在已知在索赔号中订购的数据集上完成的,那么就像以下一样简单:

df$ValuationNumber <- ave( 
 as.numeric(as.Date( as.character(df$ValuationDate), format="%m/%d/%Y")), 
 df$Claim, 
 FUN=seq_along)  # actually turned out to be some what not-easy.

如果不确定订单,您首先需要按日期排序,目前您还有非日期版本的ValuationDate。

 df <- df[order( 
          as.Date( as.character(df$ValuationDate), 
                              format="%m/%d/%Y")) , ]
 df$ValuationNumber <- ave( 
     as.numeric(as.Date( as.character(df$ValuationDate), format="%m/%d/%Y")), 
     df$Claim, 
     FUN=seq_along)