R 使用data.table按唯一值分组

R 使用data.table按唯一值分组,r,dataframe,data.table,R,Dataframe,Data.table,我有一个data.table,其中有130000多行 我想通过变量id对两个col进行分组:dates和progress,并将值放入向量中,因此我使用了aggregate() 我得到的结果是: id progress dates 1 3505H62168 1, 2 5, 6 2 3505H65277 2 2 3 3505H67158 2, 2 1, 3 4 3505H67

我有一个data.table,其中有130000多行

我想通过变量
id
对两个col进行分组:
dates
progress
,并将值放入向量中,因此我使用了
aggregate()

我得到的结果是:

          id   progress       dates
1 3505H62168       1, 2        5, 6
2 3505H65277          2           2
3 3505H67158       2, 2        1, 3
4 3505H67862          2           4
5  3505H6856 2, 2, 2, 2        7, 8, 9, 10
我很惊讶地看到,所有东西都在转换成一个
整数
+似乎包含“独立”向量的每一行实际上都是列表中的向量:

'data.frame':   5 obs. of  3 variables:
 $ id      : chr  "3505H62168" "3505H65277" "3505H67158" "3505H67862" ...
 $ progress:List of 5
  ..$ 1: int  1 2
  ..$ 2: int 2
  ..$ 3: int  2 2
  ..$ 4: int 2
  ..$ 5: int  2 2 2 2
 $ dates   :List of 5
  ..$ 1: int  5 6
  ..$ 2: int 2
  ..$ 3: int  1 3
  ..$ 4: int 4
  ..$ 5: int  7 8 9 10
我尝试使用以下格式将日期转换回正确的格式:

lapply(df_agr$dates, function(x) as.Date(x, origin="1970-01-01"))
但我得到了:

$`1`
[1] "1970-01-06" "1970-01-07"

$`2`
[1] "1970-01-03"

$`3`
[1] "1970-01-02" "1970-01-04"

$`4`
[1] "1970-01-05"

$`5`
[1] "1970-01-08" "1970-01-09" "1970-01-10" "1970-01-11"
因此,似乎起源不是文档中所写的“1970-01-01”,可能是数据中的最低日期

因此,我的问题是:如何在保持日期格式的同时,获得与
aggregate()
data.table
相同的结果

这意味着如何使用data.table按唯一id进行分组。我试过:

setDT(df)[,list(col1 = c(progress), col2 = c(dates)), by = .(unique(id))]
但我当然有以下错误:

[.data.table
中出错(df,列表(col1=c(进度),col2= c(日期)),:“按”或“按”列表中的项目长度为(5)。 每个行的长度必须与x中的行或i返回的行数相同 (10)

数据:

structure(list(id = c("3505H6856", "3505H6856", "3505H6856", 
"3505H6856", "3505H67158", "3505H67158", "3505H67862", "3505H62168", 
"3505H62168", "3505H65277"), dates = structure(c(12243, 12285, 
12299, 12341, 12066, 12101, 12117, 12166, 12187, 12094), class = "Date"), 
    progress = c("yes", "yes", "yes", "yes", "yes", "yes", "yes", 
    "no", "yes", "yes")), .Names = c("id", "dates", "progress"
), class = c("data.frame"), row.names = c(NA, -10L
))

您可以使用
paste0
我认为如下所示,您需要将日期更改为字符,这样它就不会转换为数字对应项,运行下面的查询而不将日期转换为数字将得到1216612187之类的值。在您的查询中,您还使用了“c”至于组合对象,我们应该使用粘贴来组合,在使用时也可以在data.table中使用。(id)在by中,它应该在by items上为您提供唯一的值,除非您的查询具有不唯一的内容。例如,在本例中,如果您避免使用折叠语句,您将无法获得ID上的唯一键,我希望这会有所帮助。谢谢:

df_agr <- aggregate(cbind(progress, as.character(dates)) ~ id, data = df, FUN = paste0)

> df_agr
          id           progress                                             V2
1 3505H62168            no, yes                         2003-04-24, 2003-05-15
2 3505H65277                yes                                     2003-02-11
3 3505H67158           yes, yes                         2003-01-14, 2003-02-18
4 3505H67862                yes                                     2003-03-06
5  3505H6856 yes, yes, yes, yes 2003-07-10, 2003-08-21, 2003-09-04, 2003-10-16
>
或者正如David Arenberg所指出的,更简单的数据处理方法。表是,感谢您的宝贵意见:

setDT(df)[, lapply(.SD, toString), by = id]
dplyr版本

library(dplyr)
df %>% 
   group_by(id) %>%
   summarize (progress = paste(progress, collapse=","),
              dates = paste(dates, collapse=",") )

#          id        progress                                       dates
#        <chr>           <chr>                                       <chr>
# 1 3505H62168          no,yes                       2003-04-24,2003-05-15
# 2 3505H65277             yes                                  2003-02-11
# 3 3505H67158         yes,yes                       2003-01-14,2003-02-18
# 4 3505H67862             yes                                  2003-03-06
# 5  3505H6856 yes,yes,yes,yes 2003-07-10,2003-08-21,2003-09-04,2003-10-16
库(dplyr)
df%>%
分组依据(id)%>%
汇总(进度=粘贴(进度,折叠=“,”),
日期=粘贴(日期,折叠=“,”)
#id进度日期
#                                                          
#1355H62168号,是2003-04-242003-05-15
#23505H65277是2003-02-11
#3505H67158是,是2003-01-142003-02-18
#43505H67862是2003-03-06
#是的,是的,是的,是的2003-07-102003-08-212003-09-042003-10-16

by=(id)
而不是
by=(unique(id))
@ErdemAkkas是的,但我想按unique id分组。非常感谢。使用
数据只需约2-3秒。表
而不是使用
aggregate
@davidernburg添加到解决方案中的52秒感谢您的反馈和评论。
setDT(df)[,.(paste0(progress,collapse=","), paste0(as.character(dates),collapse=",")), by = .(id)]


           id              V1                                          V2
1:  3505H6856 yes,yes,yes,yes 2003-07-10,2003-08-21,2003-09-04,2003-10-16
2: 3505H67158         yes,yes                       2003-01-14,2003-02-18
3: 3505H67862             yes                                  2003-03-06
4: 3505H62168          no,yes                       2003-04-24,2003-05-15
5: 3505H65277             yes                                  2003-02-11
setDT(df)[, lapply(.SD, toString), by = id]
library(dplyr)
df %>% 
   group_by(id) %>%
   summarize (progress = paste(progress, collapse=","),
              dates = paste(dates, collapse=",") )

#          id        progress                                       dates
#        <chr>           <chr>                                       <chr>
# 1 3505H62168          no,yes                       2003-04-24,2003-05-15
# 2 3505H65277             yes                                  2003-02-11
# 3 3505H67158         yes,yes                       2003-01-14,2003-02-18
# 4 3505H67862             yes                                  2003-03-06
# 5  3505H6856 yes,yes,yes,yes 2003-07-10,2003-08-21,2003-09-04,2003-10-16