【问题标题】:R conditional filterR条件过滤器
【发布时间】:2016-06-22 21:34:26
【问题描述】:

我在 R 中有两个数据框。

发布数据框

Date     Product
2011-01-13   A  
2011-02-15   A  
2011-01-14   B  
2011-02-15   B

案例数据数据框

Date       Product Numberofcases 
2011-01-13 A       50
2011-01-12 A       20
2011-01-11 A       100
2011-01-10 A       120
2011-01-09 A       150
2011-01-08 A       180
2011-01-07 A       200
2011-01-06 A       220
2011-01-23 A       500
2011-01-31 A       450
2011-02-08 A       50
2011-02-09 A       1000
2011-02-10 A       1200
2011-02-11 A       1500
2011-02-12 A       1800
2011-02-13 A       2000
2011-02-14 A       2200
2011-02-15 A       5000
2011-01-31 A       4500
:::
:::
2011-01-15 B       1000

我的要求是对于每个产品发布日期(来自发布数据框),我应该在发布日期前一周(在 casedata 数据框中)获得相应的总和(案例数)。即,对于产品A和发布日期2011-01-13,它应该是前一周(从2011-01-06到2011-01-13)的所有案例的总和,即,(50+20+100+ 120+150+180+200+220)

Releasedate Product Numberofcasesoneweekpriorrelease
2011-01-13  A       1040
2011-02-15  A       19250
2011-01-14  B       ...
2011-02-15  B       ...

我尝试过的:

beforerelease <- sqldf("select product,release.date_release,sum(numberofcasescreated) as numberofcasesbeforerelease from release left join casedata using (product) where date_case>=weekbeforerelease and date_case<=date_release group by product,date_release") 
finaldf <- merge(beforerelease,afterelease,by=c("monthyear","product"))

我很震惊,但它并没有给我预期的结果。有人可以帮我吗?

【问题讨论】:

  • 您提供了一些代码,谢谢。你能提供一个小样本数据集吗? (我建议使用易于复制/粘贴的东西,无论是源构建随机数据还是来自dput 的输出在一个小数据集上。)

标签: r dataframe


【解决方案1】:

data.table, v1.9.7current development version 中使用最近实现的non-equi 连接功能,这可以简单地完成(假设所有日期列都属于Date 类):

require(data.table)
setDT(release)[, Date2 := Date-7L]
setDT(casedata)[release, on = .(Product, Date >= Date2, Date <= Date), 
                .(count = sum(Numberofcases)), by = .EACHI]

#    Product       Date       Date count
# 1:       A 2011-01-06 2011-01-13  1040
# 2:       A 2011-02-08 2011-02-15 14750
# 3:       B 2011-01-07 2011-01-14    NA
# 4:       B 2011-02-08 2011-02-15    NA

【讨论】:

  • 不错!我想我错过了 non-equi 连接的介绍。
  • by = .EACHI 在这种情况下做了什么?是否等同于allow.cartesian?此外,是否有任何方法可以在 on=.(...) 参数内动态执行像 Date-7L 这样的算术运算?对于 xxl 大小的数据集,这将是 especially helpful
【解决方案2】:

使用data.table 包,您可以采用两种方法:

1) 使用foverlaps 功能:

library(data.table)
# convert to a 'data.table' with 'setDT()'
# and create a release window
setDT(release)[, `:=` (bdat = as.Date(Date)-7, edat = as.Date(Date))][, Date := NULL]
# convert to a 'data.table' and create a 2nd date column for use with 'foverlaps
setDT(casedata)[, `:=` (bdat = as.Date(Date), edat = as.Date(Date))][, Date := NULL]

# set the key for use in 'foverlaps'
setkey(release, Product, bdat, edat)
setkey(casedata, Product, bdat, edat)

# do an overlap join ('foverlaps') and summarise
foverlaps(casedata, release, type = 'within', nomatch = 0L)[, .(cases.prior.release = sum(Numberofcases)), by = .(Product, release.date = edat)]

给出:

   Product release.date cases.prior.release
1:       A   2011-01-13                1040
2:       A   2011-02-15               14750

2) 使用data.table 的标准连接功能:

setDT(release)
setDT(casedata)

casedata[, Date := as.Date(Date)
         ][release[, `:=` (Date = as.Date(Date), idx = .I)
                   ][, .(dates = seq(Date-7,Date,'day')), by = .(Product,idx)], 
           on = c('Product', Date = 'dates'), nomatch = 0L
           ][, .(releasedate = Date[.N], cases.prior.release = sum(Numberofcases)), by = .(Product,idx)
             ][, idx := NULL]

这将得到相同的结果。


使用过的数据:

release <- structure(list(Date = c("2011-01-13", "2011-02-15", "2011-01-14", "2011-02-15"), 
                          Product = c("A", "A", "B", "B")), 
                     .Names = c("Date", "Product"), class = "data.frame", row.names = c(NA, -4L))

casedata <- structure(list(Date = c("2011-01-13", "2011-01-12", "2011-01-11", "2011-01-10", "2011-01-09", "2011-01-08", "2011-01-07", "2011-01-06", "2011-01-23", "2011-01-31", "2011-02-08", "2011-02-09", "2011-02-10", "2011-02-11", "2011-02-12", "2011-02-13", "2011-02-14", "2011-02-15", "2011-01-31"), 
                           Product = c("A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A"), 
                           Numberofcases = c(50L, 20L, 100L, 120L, 150L, 180L, 200L, 220L, 500L, 450L, 50L, 1000L, 1200L, 1500L, 1800L, 2000L, 2200L, 5000L, 4500L)), 
                      .Names = c("Date", "Product", "Numberofcases"), class = "data.frame", row.names = c(NA, -19L))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-22
    • 1970-01-01
    • 1970-01-01
    • 2015-03-15
    • 2021-11-20
    • 2018-04-12
    相关资源
    最近更新 更多