相关疑难解决方法(0)

data.table vs dplyr:一个人能做得好吗,另一个做不好或做得不好?

概观

我比较熟悉data.table,而不是那么熟悉dplyr.我已经阅读了一些出现在SO上的dplyr小插曲和例子,到目前为止我的结论是:

  1. data.table并且dplyr在速度上具有可比性,除非有许多(即> 10-100K)组,并且在某些其他情况下(参见下面的基准)
  2. dplyr 有更多可访问的语法
  3. dplyr 摘要(或将)潜在的DB交互
  4. 有一些小的功能差异(参见下面的"示例/用法")

在我看来2.没有多大的重量,因为我对它很熟悉data.table,虽然我明白对于那些对这两者都不熟悉的用户来说这将是一个很重要的因素.我想避免争论哪个更直观,因为这与我从已经熟悉的人的角度提出的具体问题无关data.table.我还想避免讨论"更直观"如何导致更快的分析(当然是真的,但同样,不是我最感兴趣的).

我想知道的是:

  1. 对于熟悉软件包的人来说,是否需要使用一个或另一个软件包来编写分析任务更加容易(例如,需要按键的一些组合与所需的深奥水平相结合,其中每个项目的好处都是好事).
  2. 是否存在在一个包装与另一个包装中更有效地执行分析任务(即,超过2倍)的分析任务.

最近的一个问题让我更多地思考这个问题,因为直到那时我才认为dplyr会提供超出我已经做过的东西data.table.这是dplyr解决方案(Q末尾的数据):

dat %.%
  group_by(name, job) %.%
  filter(job != "Boss" | year == min(year)) %.%
  mutate(cumu_job2 = cumsum(job2))
Run Code Online (Sandbox Code Playgroud)

这比我的黑客尝试data.table解决方案要好得多.也就是说,好的data.table解决方案也相当不错(感谢Jean-Robert,Arun,并注意到这里我赞成对最严格的最佳解决方案的单一陈述):

setDT(dat)[,
  .SD[job != "Boss" | year == min(year)][, cumjob := cumsum(job2)], 
  by=list(id, job)
]
Run Code Online (Sandbox Code Playgroud)

后者的语法可能看起来非常深奥,但如果你习惯了data.table(即不使用一些更深奥的技巧),它实际上非常简单.

理想情况下,我希望看到的是一些很好的例子,dplyr …

r dplyr data.table

719
推荐指数
4
解决办法
11万
查看次数

如何使用data.table执行日期范围的连接?

如何使用data.table执行以下(直接使用sqldf)并得到完全相同的结果:

library(data.table)

whatWasMeasured <- data.table(start=as.POSIXct(seq(1, 1000, 100),
    origin="1970-01-01 00:00:00"),
    end=as.POSIXct(seq(10, 1000, 100), origin="1970-01-01 00:00:00"),
    x=1:10,
    y=letters[1:10])

measurments <- data.table(time=as.POSIXct(seq(1, 2000, 1),
    origin="1970-01-01 00:00:00"),
    temp=runif(2000, 10, 100))

## Alternative short names for data.tables
dt1 <- whatWasMeasured
dt2 <- measurments

## Straightforward with sqldf    
library(sqldf)

sqldf("select * from measurments m, whatWasMeasured wwm
where m.time between wwm.start and wwm.end")
Run Code Online (Sandbox Code Playgroud)

r time-series data.table

20
推荐指数
1
解决办法
4199
查看次数

重新审视 data.table 与 dplyr 内存使用

我知道data.tabledplyr 的比较是 SO 上的常客。(完全披露:我喜欢并使用这两个包。)

但是,在尝试为我正在教授的课程提供一些比较时,我遇到了令人惊讶的 wrt 内存使用情况。我的期望是dplyr在需要(隐式)过滤或数据切片的操作中表现特别差。但这不是我要发现的。相比:

首先dplyr

library(bench)
library(dplyr, warn.conflicts = FALSE)
library(data.table, warn.conflicts = FALSE)
set.seed(123)

DF = tibble(x = rep(1:10, times = 1e5),
                y = sample(LETTERS[1:10], 10e5, replace = TRUE),
                z = rnorm(1e6))

DF %>% filter(x > 7) %>% group_by(y) %>% summarise(mean(z))
#> # A tibble: 10 x 2
#>    y     `mean(z)`
#>  * <chr>     <dbl>
#>  1 A     -0.00336 
#>  2 B     -0.00702 
#>  3 C …
Run Code Online (Sandbox Code Playgroud)

r dplyr data.table

10
推荐指数
1
解决办法
752
查看次数

添加括号时,子集"data.table"的速度会降低

我最近在一些旧代码中注意到,在对a data.table进行子集化并重复执行函数时(包括计算相关矩阵),我一直包括额外的方括号.所以,

# Slow way
rcorr(DT[subgroup][, !'Group', with=F])

# Faster way
rcorr(DT[subgroup, !'Group', with=F])
Run Code Online (Sandbox Code Playgroud)

(差异在于之后subgroup).出于好奇,为什么会出现这种情况?使用额外的括号,是否data.table必须执行一些额外的计算?

r data.table

6
推荐指数
1
解决办法
115
查看次数

相对窗口运行总和通过data.table非equi连接

我有一个数据集customerId,transactionDate,productId,purchaseQty加载到data.table中.对于每一行,我想计算前45天的总和,以及购买数量的平均值

        productId customerID transactionDate purchaseQty
 1:    870826    1186951      2016-03-28      162000
 2:    870826    1244216      2016-03-31        5000
 3:    870826    1244216      2016-04-08        6500
 4:    870826    1308671      2016-03-28      221367
 5:    870826    1308671      2016-03-29       83633
 6:    870826    1308671      2016-11-29       60500
Run Code Online (Sandbox Code Playgroud)

我正在寻找这样的输出:

    productId customerID transactionDate purchaseQty    sumWindowPurchases
 1:    870826    1186951      2016-03-28      162000                162000
 2:    870826    1244216      2016-03-31        5000                  5000
 3:    870826    1244216      2016-04-08        6500                 11500
 4:    870826    1308671      2016-03-28      221367                221367
 5:    870826    1308671      2016-03-29       83633                305000
 6:    870826    1308671      2016-11-29       60500                 60500
Run Code Online (Sandbox Code Playgroud)

因此,sumWindowPurchases包含当前交易日期45天窗口内客户/产品的purchaseQty总和.一旦我有了这个工作,抛出我需要的平均值和其他计算应该是微不足道的

我回到我的SQL根源并想到了一个自我加入:

select …
Run Code Online (Sandbox Code Playgroud)

r summarization data.table

6
推荐指数
1
解决办法
424
查看次数

找到第二个数据帧中每个元素的两个数据帧之间的最小距离

我有两个数据框ev1和ev2,描述了在许多测试中收集的两种类型事件的时间戳.因此,每个数据帧都有"test_id"和"timestamp"列.我需要找到的是在同一测试中每个ev2的最小距离ev1.

我有一个工作代码合并两个数据集,计算距离,然后使用dplyr过滤最小距离:

ev1 = data.frame(test_id = c(0, 0, 0, 1, 1, 1), time=c(1, 2, 3, 2, 3, 4))
ev2 = data.frame(test_id = c(0, 0, 0, 1, 1, 1), time=c(6, 1, 8, 4, 5, 11))

data <- merge(ev2, ev1, by=c("test_id"), suffixes=c(".ev2", ".ev1"))

data$distance <- data$time.ev2 - data$time.ev1

min_data <- data %>%
  group_by(test_id, time.ev2) %>%
  filter(abs(distance) == min(abs(distance)))
Run Code Online (Sandbox Code Playgroud)

虽然这很有效,但合并部分非常慢并且感觉效率低下 - 我正在为同一个test_id生成一个包含ev2-> ev1的所有组合的巨大表格,只是将其过滤为一个.在合并期间,似乎应该有一种"即时过滤"的方法.在那儿?

更新:当使用akrun概述的data.table方法时,以下两个"group by"列的情况会失败:

ev1 = data.frame(test_id = c(0, 0, 0, 1, 1, 1), time=c(1, 2, 3, 2, 3, 4), group_id=c(0, …
Run Code Online (Sandbox Code Playgroud)

r plyr dplyr

5
推荐指数
1
解决办法
1157
查看次数

R:使用数据框A中的值从填充数据框B中的行之前的日期开始

这可能非常复杂,我怀疑需要先进的知识.我现在有两种不同类型的data.frames需要组合:

数据:

数据帧A:

按患者ID列出所有输血日期.每次输血都由一个单独的行代表,患者可以进行多次输血.不同的患者可以在同一天进行输血.

Patient ID Transfusion.Date
1          01/01/2000
1          01/30/2000
2          04/01/2003
3          04/01/2003
Run Code Online (Sandbox Code Playgroud)

B类数据帧包含其他日期的测试结果,也包括患者ID:

Patient ID  Test.Date   Test.Value
1           11/30/1999   negative
1           01/15/2000   700 copies/uL
1           01/27/2000   900 copies/uL
2           03/30/2003   negative
Run Code Online (Sandbox Code Playgroud)

我想要的是具有相同行数的Dataframe A(每次输入为1),并将最新的Test.Value作为单独的列.每个输血日期应该具有与输血最密切(之前)进行的测试的测试结果.

期望的输出:

- >

Patient ID Transfusion.Date Pre.Transfusion.Test
1          01/01/2000       negative
1          01/30/2000       900 copies/ul
2          04/01/2003       negative
3          04/01/2003       NA
Run Code Online (Sandbox Code Playgroud)

我认为一般策略是按患者ID对data.frames进行子集化.然后获取患者1的所有输血日期,检查哪个结果最接近每个元素的所有可用test_dates,然后返回最接近的值.

如何解释R来做到这一点?

编辑1:这是这些示例的R代码

df_A <- data.frame(MRN = c(1,1,2,3), 
                   Transfusion.Date = as.Date(c('01/01/2000', '01/30/2000', 
                   '04/01/2003','04/01/2003'),'%m/%d/%Y')) 

df_B <- data.frame(MRN = c(1,1,1,2), 
                   Test.Date = as.Date(c('11/30/1999', '01/15/2000', '01/27/2000', …
Run Code Online (Sandbox Code Playgroud)

join r dataframe

4
推荐指数
1
解决办法
1035
查看次数

将来自两个数据帧的信息与dplyr组合在一起

我需要一些dplyr的帮助.我有两个数据框 - 一个是巨大的,有几个时间序列A,B,...在那里(LargeDF),另一个是(Categories)有时间间隔(左边界和右边界).

我想添加另一列LargeDF,标记为leftBoundary包含适当的边界值,如下所示:

LargeDF
   ts timestamp   signal     # left_boundary
1   A 0.3209338 10.43279     # 0
2   A 1.4791524 10.34295     # 1
3   A 2.6007494 10.71601     # 2
Run Code Online (Sandbox Code Playgroud)

Categories
   ts left right
1   A    0     1
2   A    1     2
3   A    2     3
Run Code Online (Sandbox Code Playgroud)

我想出的代码是

LargeDF %>%
  group_by(ts) %>%
  do(myFUN(., Categories))

# calls this ...
myFUN <- function(Large, Categ) {
  CategTS <- Categ %>%
    filter(ts == Large[1, "ts"][[1]])

  Large …
Run Code Online (Sandbox Code Playgroud)

r dplyr data.table

4
推荐指数
1
解决办法
1674
查看次数

标签 统计

r ×8

data.table ×6

dplyr ×4

dataframe ×1

join ×1

plyr ×1

summarization ×1

time-series ×1