相关疑难解决方法(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,大约有300万行和40列.我想按照以下sql模拟代码中的组内降序对此表进行排序:

sort by ascending Year, ascending MemberID, descending Month 
Run Code Online (Sandbox Code Playgroud)

在data.table中是否有相同的方法来执行此操作?到目前为止,我必须将其分解为两个步骤:

setkey(X, Year, MemberID)
Run Code Online (Sandbox Code Playgroud)

这非常快,只需几秒钟.

X <- X[,.SD[order(-Month)],by=list(Year, MemberID)]
Run Code Online (Sandbox Code Playgroud)

这个步骤需要更长的时间(5分钟).

更新:有人发表评论X <- X[sort(Year, MemberID, -Month)]并稍后删除.这种方法似乎要快得多:

user  system elapsed 
5.560  11.242  66.236 
Run Code Online (Sandbox Code Playgroud)

我的方法:setkey()然后订购(-Month)

   user  system elapsed 
816.144   9.648 848.798 
Run Code Online (Sandbox Code Playgroud)

我现在的问题是:如果我想按年份,MemberId和sort(Year,MemberID,Month)之后的月份进行汇总,data.table是否会识别排序顺序?

更新2:回应Matthew Dowle:

在使用Year,MemberID和Month的setkey之后,每组仍然有多个记录.我想要的是总结每个小组.我的意思是:如果我使用X [order(Year,MemberID,Month)],求和是否利用data.table的二进制搜索功能:

monthly.X <- X[, lapply(.SD[], sum), by = list(Year, MemberID, Month)]
Run Code Online (Sandbox Code Playgroud)

更新3:Matthew D提出了几种方法.第一种方法的运行时间比order()方法快:

   user  system elapsed 
  7.910   7.750  53.916 
Run Code Online (Sandbox Code Playgroud)

马修:让我感到惊讶的是大部分时间转换月份的标志.没有它,setkey的速度非常快.

performance r data.table

51
推荐指数
2
解决办法
4万
查看次数

如何通过不同的列名合并两个data.table?

我有两个data.table Xÿ.

X:area, id, value
在列ÿ:ID, price, sales

创建两个data.tables:

X = data.table(area=c('US', 'UK', 'EU'),
               id=c('c001', 'c002', 'c003'),
               value=c(100, 200, 300)
              )

Y = data.table(ID=c('c001', 'c002', 'c003'),
               price=c(500, 200, 400),
               sales=c(20, 30, 15)
              )
Run Code Online (Sandbox Code Playgroud)

我为XY设置了键:

setkey(X, id)
setkey(Y, ID)
Run Code Online (Sandbox Code Playgroud)

现在,我尝试加入XŸ通过idXIDÿ:

merge(X, Y)
merge(X, Y, by=c('id', 'ID'))
merge(X, Y, by.x='id', by.y='ID')
Run Code Online (Sandbox Code Playgroud)

所有引发的错误都说明by参数中的列名无效.

我参考了data.table手册,发现merge函数不支持 …

merge r data.table

27
推荐指数
3
解决办法
4万
查看次数

合并具有不同列名的表

如果我理解正确,默认情况下,data.table通过比较设置为键并具有相同名称的列来合并两个表.如果我有不同列名的表,我该怎么写?例如:

set.seed(123)
DT1<-data.table(col1=sample(letters,5,replace=TRUE),col2=sample(LETTERS[1:5],5,replace=TRUE),col3=sample(1:2,5,replace=TRUE))
DT2<-data.table(col4=sample(1:3,10,replace=TRUE),col5=sample(LETTERS[1:5],10,replace=TRUE),col6=sample(1:100,10,replace=TRUE))
(DT1)
(DT2)

> (DT1)
   col1 col2 col3
1:    h    A    2
2:    u    C    1
3:    k    E    2
4:    w    C    2
5:    y    C    1
> (DT2)
    col4 col5 col6
 1:    3    D   48
 2:    1    C   76
 3:    1    C   22
 4:    1    B   32
 5:    3    A   24
 6:    3    E   15
 7:    3    E   42
 8:    2    D   42
 9:    3    D   37
10:    2    A   16
Run Code Online (Sandbox Code Playgroud)

我应该写什么DT1[ …

merge r data.table

7
推荐指数
1
解决办法
4689
查看次数

在 R data.table 中连接具有相同(非键控)列名的表

加入data.tables 时如何处理同名的非键列?我正在寻找table.fieldSQL 中符号的解决方案。

例如,假设我有一个表 DT,v 每个时间段都会为列重新填充新数据。我还有一个表 DT_HIST,用于存储以前时间段 ( t) 的条目。我想找到每个时间段当前和上一个时间段之间的差异x

在这种情况下:DT是时间段3,DT_HIST有时间段1和2:

 DT <- data.table(x=c(1,2,3,4),v=c(20,20,35,30))
 setkey(DT,x)
 DT_HIST <- data.table(x=rep(seq(1,4,1),2),v=c(40,40,40,40,30,25,45,40),t=c(rep(1,4),rep(2,4)))
 setkey(DT_HIST,x)

> DT
   x  v
1: 1 20
2: 2 20
3: 3 35
4: 4 30

> DT_HIST
   x  v t
1: 1 40 1
2: 1 30 2
3: 2 40 1
4: 2 25 2
5: 3 40 1
6: 3 45 2
7: 4 40 1
8: 4 40 2
Run Code Online (Sandbox Code Playgroud)

我想加盟DT与 …

join r data.table

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

标签 统计

data.table ×5

r ×5

merge ×2

dplyr ×1

join ×1

performance ×1