【问题标题】:Remove identical sequence of same numbers from data frame/vector从数据框/向量中删除相同数字的相同序列
【发布时间】:2012-12-06 15:21:29
【问题描述】:

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

我从创建垃圾箱开始:

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

“coKey”是“公司代码”。

我无法通过留下最后一次观察来清理数据,我也未能成功地将 bin 反转到原始数据框中,因为这样做的过程太过时了。

非常感谢您的帮助,非常感谢。

这是示例数据。

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")

【问题讨论】:

  • 欢迎来到 Stack Overflow。您可以使用dput(dataFrame) 或其中的一部分dput(head(dataFrame, 30)) 吗?这样我们就可以准确地看到您正在处理的内容。
  • 您的 def 列是否看起来像 1111111(单个字符串)或像 c(1, 1, 1, 1, 1, 1)(1 的向量)
  • 谢谢贾斯汀:这是输出:> dput(head(dataMod)) structure(list(fyear = 1981:1986, gvkey = c(1004L, 1004L, 1004L, 1004L, 1004L, 1004L) , DEF = 结构(c(1L, 1L, 1L, 1L, 1L, 1L), .Label = c("0", "1"), class= "factor")), .Names = c("fyear" , "gvkey", "DEF"), row.names = c(NA, 6L), class= "data.frame")
  • 对不起。 “gvkey”是 coKey=company 代码。 dataMod 是数据帧。列 DEF 是默认的“def”列(零表示无默认值,1 表示默认值)。 fyear,是给定 gvkey 的公司的财政年度。我最初的尝试是将数据帧的样本作为 jpg 文件放置,但由于它的新帐户不允许。
  • Ricardo: 是一个 1 的向量,每个对应于同一公司(如果默认)代码(coKey=cvKey 即 1004),表示从公司成立到公司移除 = 默认的年数。

标签: database r


【解决方案1】:

在阅读了您的 cmets 之后,我相信这就是您想要的,但我不确定。

#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

【讨论】:

  • 既要避免数据中可能出现NA 的问题,又要简化,用res&lt;-c(rep(0,length(x)-1),1) 替换res &lt;- x*0 ;res[length(res)] &lt;- 1 怎么样?
  • 当然可以。但是,前者对大向量更有效,这对 OP 来说很可能不是问题。
【解决方案2】:

看来您确实需要先拆分数据,如果 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)

【讨论】:

    【解决方案3】:

    听起来您正在尝试将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
    

    【讨论】:

    • 谢谢里卡多。抱歉我的解释不完善。基本上我的数据框包含 3 列。第 1 列年份、第 2 列公司代码和第 3 列默认值(0 表示无默认值,1 表示默认值)。但是,如果公司在 2000 年违约,并且我的数据框包含 1990 年的公司财务状况,则该特定公司的列(公司代码即 1004)在“def”列中有 10 乘以 1。而是应该是 1990 = 0, 1991 = 0, 1992 = 0 .... 1999 = 0, 2000 = 1。
    • 所以你想把所有的 0 都放在一列吗?他们应该如何表现? 000001, c(0, 0, 0, 0, 1)?
    • yes as c(0,0,0...1),但是现在已经完成了,非常感谢您的付出和帮助。
    猜你喜欢
    • 2012-01-13
    • 1970-01-01
    • 2020-09-28
    • 2020-11-17
    • 2022-12-06
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多