Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 可伸缩地提取大型数据表中每个组的最后n行_R_Performance_Group By_Data.table_Tail - Fatal编程技术网

R 可伸缩地提取大型数据表中每个组的最后n行

R 可伸缩地提取大型数据表中每个组的最后n行,r,performance,group-by,data.table,tail,R,Performance,Group By,Data.table,Tail,我在网上找到了几种可以用来完成这项任务的解决方案。然而,它们似乎都不能在R中伸缩。实现这一点的最佳方法是什么 问题描述: 数据:DT或DF是一个包含id列和大量随机数据的表 该表已按id排序(由于构造原因) 任务:提取表中每个id的最后n行 library(data.table) library(dplyr) library(magrittr) # config set.seed(20160313) num.rows = 10^5 # build data set DT <- data

我在网上找到了几种可以用来完成这项任务的解决方案。然而,它们似乎都不能在R中伸缩。实现这一点的最佳方法是什么

问题描述:
数据:DT或DF是一个包含id列和大量随机数据的表 该表已按id排序(由于构造原因)

任务:提取表中每个id的最后n行

library(data.table)
library(dplyr)
library(magrittr)

# config
set.seed(20160313)
num.rows = 10^5

# build data set
DT <- data.table( c1=runif(num.rows) )
for( i in 2:9 )
    DT[[paste0("c",i)]] <- runif(num.rows)

DT$id <- 1:num.rows %/% 4

# solution with data.table
setkey(DT,id)
cat( "solution: data.table\n" )
print(system.time(
    t1 <- DT[,tail(.SD,n=n),by=id]
))

# solution with dplyr
DF <- as.data.frame(DT)
cat( "solution: dply\n" )
print(system.time(
    t2 <- DF %>% group_by(id) %>% do( tail(.,n=n) )
))

# second solution with dplyr
cat( "solution: dplyr 2\n" )
print(system.time({
    t3 <- DF %>% group_by(id) %>% filter(rank(-row_number()) <= n)
}))


# solution with by command
cat( "solution: by\n" )
print(system.time( {
    temp <- by( DT, DT$id, tail, n=n )
    t4 <- do.call( "rbind", as.list( temp ) )
}))

# solution using split and lapply
cat( "solution: split and lapply\n" )
print(system.time( {
    temp <- split(DT,DT$id)
    temp <- lapply(temp, tail, n=n)
    t5 <- do.call( "rbind", temp )
}))

cat( "solution: via data.table 3\n" )
print(system.time( {
    t6 <- DT[DT[,tail(.I,n),by=id]$V1,]
}))


# failsafe checks
if( all(t1$c1 == t2$c1) )
    cat( "1==2 OK\n" )
if( all(t1$c1 == t3$c1) )
    cat( "1==3 OK\n" )
if( all(t1$c1 == t4$c1) )
    cat( "1==4 OK\n" )
if( all(t1$c1 == t5$c1) )
    cat( "1==5 OK\n" )
if( all(t1$c1 == t6$c1) )
    cat( "1==6 OK\n" )
用于其他n

system.time( DT[DT[,tail(.I,n),by=id]$V1,] )
# for n=2
#   user  system elapsed 
# 33.740   0.112  33.872

# for n=3
#   user  system elapsed 
# 33.988   0.184  34.194

这看起来还是有点过分,但它对我的情况有效。

您是否尝试了
unique(DT,by=“id”,fromLast=TRUE)
?或者
DT[!复制(DT$id,fromLast=TRUE)]
?太好了!对于具体问题来说,这很好。谢谢但是,如果我们想使用(比方说)最后两行,问题仍然存在。最后(最多)行的一个可能的替代方法是
DT[,.SD[.N],by=id]
:DT[DT[,tail(.I,N),by=id]$V1]@user2957945 David通过关闭它回答了OP最初的问题。然后OP将他们的问题扩展到你现在看到的(这不是很好的礼仪)也许我应该恢复他们的编辑,只显示原始问题?我同意,像现在这样,问题包含答案内容是很尴尬的。。。但似乎还可以忍受。无论如何,我找到了一些更相关的问题,并将它们添加到重复列表中。
system.time( DT[DT[,tail(.I,n),by=id]$V1,] )
# for n=2
#   user  system elapsed 
# 33.740   0.112  33.872

# for n=3
#   user  system elapsed 
# 33.988   0.184  34.194