第一次看到特定观察后如何删除行

时间:2018-01-12 05:15:37

标签: r database bigdata data-modeling finance

我有一个数据集,其中我有每个观察的帐号和“过期日期”。对于每个帐号,只要“天数过期”列点击“DLQ3”之类的代码,我就会删除该帐户的其余行(即使DLQ3是该帐户的第一个观察点)。

我的数据集如下:

Obs_month  Acc_No       OS_Bal      Days_past_due
201005     2000000031   3572.68     NORM
201006     2000000031   4036.78     NORM
200810     2000000049   39741.97    NORM
200811     2000000049   38437.54    DLQ3
200812     2000000049   23923.98    DLQ1
200901     2000000049   35063.88    NORM

因此,对于帐户2000000049,我想删除200812日期之后的所有行,因为它现在是默认的。

总而言之,我希望看到帐户何时达到DLQ3以及何时进行,我想在第一次DLQ3观察后删除所有行。

我尝试的是使用所有DLQ3观察对数据进行子集化,并按升序对观察月进行排序,并获得具有DLQ3及其第一个月达到DLQ3的帐号的唯一列表。帖子,我以为我可以用原始数据做一些left_join并使用ifelse,但流程是冒险的。

2 个答案:

答案 0 :(得分:0)

以下功能将扫描您的数据框并找到包含 DLQ3 标记的行。然后,它将删除该标记之后出现的该帐号的所有行。

scan_table <- function(data_frame, due_column, acct_column, due_tag) {
    for(i in 1:nrow(data_frame)) {
        if(data_frame[i,c(due_column)] == due_tag) {
            # remove rows past here, for this account 
            acct_num <- data_frame[i,c(acct_column)]
            top_frame <- data_frame[1:i,] # cut point
            sub_frame <- subset(data_frame, Acc_No != acct_num)
            final_frame <- unique(do.call('rbind', list(top_frame, sub_frame)))
            return(final_frame)
        }
    }
}

示例

df

enter image description here

<强>用法:

scan_table(df, 'Days_past_due', 'Acc_No', 'DLQ3')

enter image description here

如果您想要不同的东西,请告诉我。

答案 1 :(得分:0)

给出你的例子

data <- read.table(text=
"Obs_month  Acc_No       OS_Bal      Days_past_due
201005     2000000031   3572.68     NORM
201006     2000000031   4036.78     NORM
200810     2000000049   39741.97    NORM
200811     2000000049   38437.54    DLQ3
200812     2000000049   23923.98    DLQ1
200901     2000000049   35063.88    NORM", stringsAsFactors=F, header=T)

我会对它进行排序

data <- data[with(data, order(Acc_No, Obs_month)), ]

并定义一个函数,允许您设置指示到期的代码(&#34; DLQ3&#34;或&#34; DLQ1&#34;来自您的示例)

sbst <- function(data, pattern){
  if( all(data$Days_past_due %in% "NORM") == TRUE){
    return(data)} else{
      indx <- min(grep(1, match(data$Days_past_due, pattern, nomatch = 0)))
      data <- data[1:indx,]
      return(data)
    }
}

最后,应用该函数并将data.frame列表聚合到最终的data.frame

Reduce(rbind, lapply(split(data, data$Acc_No), sbst, patter="DLQ3"))
#  Obs_month     Acc_No   OS_Bal Days_past_due
#1    201005 2000000031  3572.68          NORM
#2    201006 2000000031  4036.78          NORM
#3    200810 2000000049 39741.97          NORM
#4    200811 2000000049 38437.54          DLQ3