使用R中的data.table高效分组

使用R中的data.table高效分组,r,dplyr,data.table,R,Dplyr,Data.table,可以缩写以下脚本: 不要使用如此多的链式操作。 尽量避免使用.SD和by 原始代码是使用dplyr的纸条: 下面是一个没有链接或.SD的解决方案: 你好,赫克劳!感谢您发布一个小示例和您尝试过的代码。你能用语言描述一下你想要达到的目标吗。这将使人们更容易帮助你,也使你的文章对未来的访问者更有价值。干杯。我能理解你为什么要尽量避免使用.SD和by吗?同意@MichaelChirico。你还需要澄清你所说的高效团队是什么意思。我认为您在I DT[,.I[bucket==minbucket],by=t

可以缩写以下脚本:

不要使用如此多的链式操作。 尽量避免使用.SD和by 原始代码是使用dplyr的纸条:


下面是一个没有链接或.SD的解决方案:


你好,赫克劳!感谢您发布一个小示例和您尝试过的代码。你能用语言描述一下你想要达到的目标吗。这将使人们更容易帮助你,也使你的文章对未来的访问者更有价值。干杯。我能理解你为什么要尽量避免使用.SD和by吗?同意@MichaelChirico。你还需要澄清你所说的高效团队是什么意思。我认为您在I DT[,.I[bucket==minbucket],by=title]$V1中为每个组选择相关行的方式是一种规范的方法;例如,请参见,$V1从data.table中选择列V1并返回向量。如果按组进行计算而不命名结果,则V1是默认名称。玩一个较小的例子,并将其分解为以下步骤:d=data.tablex=c2,1,4,3,g=ca,a,b,b;使用.I获取行名称:d[,.I];分组最小值:d[,minx,by=g];检查x是否为min:d[,x==minx,by=g]-注意V1;使用前面的布尔值index.I:d[,.I[x==minx],by=g],再次使用默认名称V1。我们可以主动命名结果,例如d[,.min_rows=.I[x==minx],by=g],但我们很懒,很快我们就会记住默认名称是V1。提取所需的最小行作为向量:d[,.I[x==minx],by=g]$V1。最后,使用索引向量对第一个插槽中的原始数据i进行子集:d[d[,.i[x==minx],by=g]$V1]。sindri_baldur,感谢您的代码,它比我展示的代码更容易阅读。我真的很喜欢使用data.table包,在我的一点经验中,我第一次看到了一个更易于阅读的dplyr代码来解决这个任务。你的代码让我很开心!遵循@sindri_baldur:DT[,{V1]的思想
library(data.table)
DT<-structure(list(title = c("a", "a", "a", "a", "b", "b", "b", "b", "c", "c", "c", "c", "d", "d", "d", "d"), date = c("12-07-2020", "13-07-2020", "14-07-2020", "15-07-2020", "12-07-2020", "13-07-2020", 
         "14-07-2020", "15-07-2020", "12-07-2020", "13-07-2020", "14-07-2020", "15-07-2020", 
         "12-07-2020", "13-07-2020", "14-07-2020", "15-07-2020"), 
bucket = c(1, 1, 1, 4, 9, 7, 10, 10, 8, 5, 5, 5, 8, 10, 9, 10), 
score = c(86, 22, 24, 54, 66, 76, 43, 97, 9, 53, 45, 40, 21, 99, 91, 90)),
 row.names = c(NA, -16L), class = c("data.table","data.frame"))
 
DT[DT[, .I[bucket == min(bucket)], by = title]$V1]
DT[, .SD[which(bucket == min(bucket))], by =title][,
  `:=`(avg_score = mean(score)), by = .(title)][,
    .SD[.N,c(1,2,4)], by = .(title)]                                                                                                     

tt <- data %>% 
group_by(title) %>% 
filter(bucket == min(bucket)) %>% 
mutate(avg_score = mean(score)) %>% 
slice_max(date) %>% 
select(-score)
>
title date       bucket avg_score
  <chr> <chr>       <dbl>     <dbl>
1 a     14-07-2020      1        44
2 b     13-07-2020      7        76
3 c     15-07-2020      5        46
4 d     12-07-2020      8        21
> 
# Convert from character to Date to be able to select the max
DT[, date := as.Date(date, "%d-%m-%Y")]

DT[,
   {
     mb <- which(bucket == min(bucket))
     .(
       date = max(date[mb]), bucket = bucket[mb][1L], avg_score = mean(score[mb])
     )
   }, 
   by = title]

#    title       date bucket avg_score
# 1:     a 2020-07-14      1        44
# 2:     b 2020-07-13      7        76
# 3:     c 2020-07-15      5        46
# 4:     d 2020-07-12      8        21