从数据框/向量中删除相同数字的相同序列

时间:2012-12-06 15:21:29

标签: database r

我有一个数据集,其中包含“年”,“公司代码”和“def - 公司是否违约”的列。我遇到的问题是“def”列默认包含一个“1”序列。这些“1”是公司运营的所有年份。因此,例如该公司从1990年开始运营,并在2000年停业。该栏目包含10倍“1”,即使该公司在去年即2000年违约。所以我应该在这个特定的“公司”代码“仅”1“2000年的默认条目,而不是1990 - 2000年的整个年份。如何从“def”列中删除“1”的序列(我现在将其作为data.frame)并将最后一个“1”作为实际默认值?

我已经开始创建垃圾箱了:

split(data.frame[dataFrame$def == 1, ], dataFrame[dataFrame$def == 1, 'coKey]) 

其中'coKey'是“公司代码”。

我无法通过留下最后一次观察来清理数据,也没有成功将垃圾箱转换为原始数据框,因为这样做的过程太过时了。

非常感谢你的帮助。

以下是样本数据。

dataFrame <- structure(list(fyear = 1981:1986, 
   gvkey = c(1004L, 1004L, 1004L, 1004L, 1004L, 1004L), 
   def = structure(c(1L, 1L, 1L, 1L, 1L, 1L ), 
   .Label = c("0", "1"), class = "factor")), 
   .Names = c("fyear", "coKey", "def"), 
   row.names = c(NA, 6L), class = "data.frame")

3 个答案:

答案 0 :(得分:1)

听起来你要做的就是将一串111's'转换成一个1。如果是这种情况,以下应该这样做。

逐步分解:

# Likely they're factors.  Convert to strings.  # Dont convert to numeric if your data may have a series of approx 20+ 1's 
dataFrame$def <- as.character(dataFrame$def)

# Find which ones have any 1's at all
indxOf1s <- grep("1", dataFrame$def)

# Convert those to a single 1
  x <- gsub("1", "0", dataFrame$def[indxOf1s])    
  dataFrame$def[indxOf1s] <-  paste0(substr(x, 1, nchar(x)-1), rep(1, length(x)) )

dataFrame

        BEFORE      &          AFTER

    Comp    def             Comp    def
  1    A   1111           1    A   0001
  2    B   1111           2    B   0001
  3    C      0           3    C      0
  4    D 111111           4    D 000001
  5    E      1           5    E      1
  6    F 111111           6    F 000001
  7    G 111111           7    G 000001
  8    H  11111           8    H  00001

答案 1 :(得分:1)

看起来你真的需要首先拆分数据,如果def列中有1,那么将非最大年份的所有内容更改为0,然后将它重新组合在一起。

l <- split(dataFrame, data.Frame$coKey)
l <- lapply(l, function(x){ 
               if (1 %in% x$def) x$def[x$fyear != max(x$fyear)] <- 0
               x})
data.Frame <- do.call(rbind, l)

答案 2 :(得分:1)

阅读完你的评论后,我相信这就是你想要的,但我不确定。

#Example data
df <- data.frame(fyear=rep(1981:1990,2),
                 gvkey=rep(c(1004,1005),each=10),
                 DEF=c(rep(0,2),rep(1,3),rep(0,5),rep(1,7),rep(0,3)))


library(plyr)

#function to apply by company
myfun <- function(x) {
  #check if last value is a 1
  if (last(x)==1) {
   res <- x*0
   res[length(res)] <- 1
  } else {
    #seach for difference between values == -1
    res <- as.numeric(c(diff(x),0)==-1)
  }
  res  
}

#split-apply-combine
ddply(df,~gvkey,transform,DEF2 = myfun(DEF))

结果:

  fyear gvkey DEF DEF2
1   1981  1004   0    0
2   1982  1004   0    0
3   1983  1004   1    0
4   1984  1004   1    0
5   1985  1004   1    1
6   1986  1004   0    0
7   1987  1004   0    0
8   1988  1004   0    0
9   1989  1004   0    0
10  1990  1004   0    0
11  1981  1005   1    0
12  1982  1005   1    0
13  1983  1005   1    0
14  1984  1005   1    0
15  1985  1005   1    0
16  1986  1005   1    0
17  1987  1005   1    1
18  1988  1005   0    0
19  1989  1005   0    0
20  1990  1005   0    0