【问题标题】:dplyr and checking previous 24-60 months for observationsdplyr 并检查前 24-60 个月的观察结果
【发布时间】:2015-04-09 07:42:14
【问题描述】:

我有一堆唯一的 cusip 代码(唯一 ID),需要检查以确保上个月有 24-60 次观察,但不知道如何使用 dplyr 进行检查

可重现的例子:

tdata <- structure(list(cusip = c(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2), fyear = c("1971", "1971", "1971", "1971", 
"1971", "1971", "1971", "1971", "1971", "1971", "1971", "1971", 
"1972", "1972", "1972", "1972", "1972", "1972", "1972", "1972", 
"1972", "1972", "1972", "1972", "1972", "1973", "1973", "1973", 
"1973", "1973", "1973", "1973", "1973", "1973", "1973", "1973", 
"1973", "1974", "1974", "1974", "1974", "1974", "1974", "1974", 
"1974", "1974", "1974", "1974", "1974", "1975", "1975", "1975", 
"1975", "1975", "1975", "1975", "1975", "1975", "1975", "1975"
), datadate = c(19711231L, 19710129L, 19710226L, 19710331L, 19710430L, 
19710528L, 19710630L, 19710730L, 19710831L, 19710930L, 19711029L, 
19711130L, 19721231L, 19720131L, 19720229L, 19720330L, 19720428L, 
19720531L, 19720630L, 19720731L, 19720831L, 19720929L, 19721031L, 
19721130L, 19721229L, 19731231L, 19730131L, 19730228L, 19730330L, 
19730430L, 19730531L, 19730629L, 19730731L, 19730831L, 19730928L, 
19731031L, 19731130L, 19741231L, 19740131L, 19740228L, 19740329L, 
19740430L, 19740531L, 19740628L, 19740731L, 19740830L, 19740930L, 
19741031L, 19741129L, 19751231L, 19750131L, 19750228L, 19750331L, 
19750430L, 19750530L, 19750630L, 19750731L, 19750829L, 19750930L, 
19751031L)), .Names = c("cusip", "fyear", "datadate"), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -60L), vars = list(
    cusip, fyear), drop = TRUE, indices = list(0:11, 12:24, 25:36, 
    37:48, 49:59), group_sizes = c(12L, 13L, 12L, 12L, 11L), biggest_group_size = 13L, labels = structure(list(
    cusip = c(2, 2, 2, 2, 2), fyear = c("1971", "1972", "1973", 
    "1974", "1975")), class = "data.frame", row.names = c(NA, 
-5L), .Names = c("cusip", "fyear"), vars = list(cusip, fyear)))

逻辑

我正在考虑检查每年的总月数,但不知道提取前几个月来检查 24/60 >= 0.4。我将如何编辑此代码以检查前 60 个月并确保至少有 24 个月,包括....

tdata %>% 
  group_by(cusip, fyear) %>% 
  mutate(month = substr(datadate, 5, 6) %>% 
  mutate(pre_countmonths = length(unique(month))

编辑 04/07/2015 :

这是我使用 for 循环所遵循的逻辑。我在使用 R 时遇到的挑战之一是在 for 循环之外进行分支。任何可能的方法来编辑这个可以使用dplyr 而不是for 循环?使用我当前的数据运行这将花费很长时间。

for(i in min(tdata$cusip):max(tdata$cusip)){ 
    for (j in min(tdata$fyear):max(tdata$fyear) {
      monthcheck <- filter(tdata, cusip == i & (fyear == j-1 | fyear == j-2 | fyear == j-3 | fyear == j-4))
      if(length(monthcheck$month) / 40 >= 0.4) if(any(tdata$fyear == j)) tdata$check <- 1 
}}

编辑:04/08/2015 - 添加了包含主要变量的完整示例数据集

小子集:https://www.dropbox.com/s/mf0o0tbgbame6k8/testdata.csv?dl=0

【问题讨论】:

  • 您想知道是否有超过 24 个先前的数据点从每个 cusip 的最后一次观察开始计数。对吗?
  • @jazzurro 对于每个 cusip 和年份...此数据集从 7 月开始,因此它应该反映从 6 月开始的前两年...。
  • 这是否意味着您想知道在此示例中从 1975-07-31 倒数的数据点是否超过 24 个?
  • 是的,但它需要是几个月,而不是观察,因为个别公司可能不是每个月都报告,应该删除那些因为我需要连续报告 24-60 个月

标签: r dplyr


【解决方案1】:

这是我在时限内得到的。我希望这能给你一些想法,也希望其他用户提供更好的解决方案。

mydf <- as_data_frame(list(cusip = c(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2), fyear = c("1971", "1971", "1971", "1971", 
"1971", "1971", "1971", "1971", "1971", "1971", "1971", "1971", 
"1972", "1972", "1972", "1972", "1972", "1972", "1972", "1972", 
"1972", "1972", "1972", "1972", "1972", "1973", "1973", "1973", 
"1973", "1973", "1973", "1973", "1973", "1973", "1973", "1973", 
"1973", "1974", "1974", "1974", "1974", "1974", "1974", "1974", 
"1974", "1974", "1974", "1974", "1974", "1975", "1975", "1975", 
"1975", "1975", "1975", "1975", "1975", "1975", "1975", "1975"
), datadate = c(19711231L, 19710129L, 19710226L, 19710331L, 19710430L, 
19710528L, 19710630L, 19710730L, 19710831L, 19710930L, 19711029L, 
19711130L, 19721231L, 19720131L, 19720229L, 19720330L, 19720428L, 
19720531L, 19720630L, 19720731L, 19720831L, 19720929L, 19721031L, 
19721130L, 19721229L, 19731231L, 19730131L, 19730228L, 19730330L, 
19730430L, 19730531L, 19730629L, 19730731L, 19730831L, 19730928L, 
19731031L, 19731130L, 19741231L, 19740131L, 19740228L, 19740329L, 
19740430L, 19740531L, 19740628L, 19740731L, 19740830L, 19740930L, 
19741031L, 19741129L, 19751231L, 19750131L, 19750228L, 19750331L, 
19750430L, 19750530L, 19750630L, 19750731L, 19750829L, 19750930L, 
19751031L)))

# Make it normal data.frame
mydf <- data.frame(mydf)

# Create another data frame with a new cusip
mydf2 <- mutate(mydf, cusip = 3)

### Create a new data frame which is missing one data point
foo <- bind_rows(mydf, mydf2[-4, ])

在这个伪数据中,cusip 3 缺少一个月的数据。这意味着,您没有cusip 3 的连续 24-60 个月数据。首先,我创建了一个包含月份的列和一个包含日期对象的列。然后,我通过cusp 和数据日期订购了您的数据。我想选择保持在这 24-60 个月期间的数据点。这是第一个filter 部分。我将数据按cusp 分组。使用月份,我想检查我是否有连续的数据点。您会期望 lead(month)-month = 1、11 或 0。如果您有来自同一个月的两个数据点,您会期望 0。这发生在您的数据中。最后的filter 是您可以修改的。在这里,我想删除任何检查了 FALSE 的cusip。在这个草稿中,这个过滤器似乎在做正确的事情;你最终没有看到 cusip 3 的任何数据。希望对您有所帮助。

mutate(foo, month = as.numeric(substr(datadate, 5, 6))) %>%
mutate(datadate = as.POSIXct(gsub("^(\\d{4})(\\d{2}).*$", "\\1-\\2-01", datadate),
                  format("%Y-%m-%d"), tz = "GMT")) %>%  
arrange(cusip, datadate) %>%                        
filter(between(datadate, 
       datadate[tail(which(month == 6, arr.ind = TRUE), n = 1)] - (60*60*24*30*60),
       datadate[tail(which(month == 6, arr.ind = TRUE), n = 1)] -(60*60*24*30*24))) %>%
group_by(cusip) %>%
mutate(check = abs(lead(month)-month) == 11|abs(lead(month)-month) == 1|abs(lead(month)-month) == 0) %>%
filter(all(check == TRUE | check %in% NA)) 

【讨论】:

  • 将其应用于更大的数据集后,第一个 filter 命令似乎无法正常工作。我已经完成了它,这会返回 0 obs....知道为什么吗?我没有遵循这一步的逻辑
  • @Amstell 您的数据中有几个带有六月的数据点。我想拿起最后一个。我已经用datadate[tail(which(month == 6, arr.ind = TRUE), n = 1)] 做到了。使用这个数据点,我想获取前 24 到 60 个月之间的数据点。例如,(60*60*24*30*60) 相当于 6 个月。简而言之,过滤器是过滤 ​​24-60 个月期间的数据。我不确定为什么过滤器不适用于您的数据;它在我的机器上工作。我想知道我这里的示例数据和您的真实数据之间是否有任何差异。
  • 感谢您的解释...您创建的示例代码运行良好,但不适用于完整的数据集。我已将其添加到问题中,只需要 3 个变量。我用这个检查了它,它仍然返回 0。知道发生了什么吗?
  • @Amstell 我下载了您的文件并测试了上面的代码。我最后有 179866 个 obs。因此,代码似乎正在使用新的示例数据。我不确定为什么在第一次过滤后您什么也没有收到。
  • 你说得对,它确实有效。我在使用dplyr 进行分组时遇到了问题,所以我取消了数据框的分组并运行它....作品得到....谢谢....你能解释一下(60*60*24*30*60) 是6 个月吗?我不明白这个
猜你喜欢
  • 2014-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-07
  • 1970-01-01
相关资源
最近更新 更多