Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/76.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 仅获取具有给定行数的data.table组_R_Data.table - Fatal编程技术网

R 仅获取具有给定行数的data.table组

R 仅获取具有给定行数的data.table组,r,data.table,R,Data.table,我有以下数据表: dt = data.table(year=c(1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2), quar=c(1, 1, 1, 2, 2, 3, 4, 4, 4, 1, 1, 1), item=c(1, 2, 3, 1, 2, 1, 1, 2, 3, 1, 2, 3)) 某些按年度和季度定义的期间有三项: Y1Q1、Y1Q4、Y2Q1 其他时段没有: Y1Q2有2个项目 Y1Q3有1个项目

我有以下数据表:

dt = data.table(year=c(1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2),
                quar=c(1, 1, 1, 2, 2, 3, 4, 4, 4, 1, 1, 1),
                item=c(1, 2, 3, 1, 2, 1, 1, 2, 3, 1, 2, 3))
某些按年度和季度定义的期间有三项:

Y1Q1、Y1Q4、Y2Q1 其他时段没有:

Y1Q2有2个项目 Y1Q3有1个项目 我如何才能只获取包含所有三项的行

到目前为止,我所做的是

dt[dt[, "i" := nrow(.SD) == 3, .(year, quar)]$i]
> year | quar | item | i
> -----+------+------+-----
> 1    | 1    | 1    | TRUE
> 1    | 1    | 2    | TRUE
> 1    | 1    | 3    | TRUE
> 1    | 4    | 1    | TRUE
> 1    | 4    | 2    | TRUE
> 1    | 4    | 3    | TRUE
> 2    | 1    | 1    | TRUE
> 2    | 1    | 2    | TRUE
> 2    | 1    | 3    | TRUE
按年份和quar分组,然后设置一列i,说明该组是否有效。组中的所有行都获得i的计算值

这很好用。但是,它的副作用是向表中添加一个实i列

我尝试使用一个用.I=….声明的临时列,但是I列的长度与较短的分组表相同,我们得到

dt[dt[, .(i = nrow(.SD) == 3), .(year, quar)]$i]
> Error in `[.data.table`(dt, dt[, .(i = nrow(.SD) == 3), .(year, quar)]$i) :
> i evaluates to a logical vector length 5 but there are 12 rows. [...]

那么,有没有更优雅的方法来解决这个问题?或者我应该使用这个,然后删除I吗?

如果我们需要子集,请使用.I来获取行索引和子集

dt[dt[, .I[.N == 3], .(year, quar)]$V1]
#    year quar item
#1:    1    1    1
#2:    1    1    2
#3:    1    1    3
#4:    1    4    1
#5:    1    4    2
#6:    1    4    3
#7:    2    1    1
#8:    2    1    2
#9:    2    1    3
或者使用.SD,但速度可能较慢

dt[, .SD[.N == 3], .(year, quar)]
或者另一个选项是if/else


如果需要子集,请使用.I来获取行索引和子集

dt[dt[, .I[.N == 3], .(year, quar)]$V1]
#    year quar item
#1:    1    1    1
#2:    1    1    2
#3:    1    1    3
#4:    1    4    1
#5:    1    4    2
#6:    1    4    3
#7:    2    1    1
#8:    2    1    2
#9:    2    1    3
或者使用.SD,但速度可能较慢

dt[, .SD[.N == 3], .(year, quar)]
或者另一个选项是if/else

当然,这是一个data.table问题,@akrun的回答涵盖了这一点,但为了完成

dplyr解决方案:

图书馆弹琴 dt%>%group_按年,quar%>%filtern==3 一个tibble:9x3 组:年,夸尔[3] 年度夸尔项目 1 1 1 1 2 1 1 2 3 1 1 3 4 1 4 1 5 1 4 2 6 1 4 3 7 2 1 1 8 2 1 2 9 2 1 3 基本上:

dt[avedt$item,dt[,cyear,quar],FUN=length==3,] 或

freqt当然这是一个data.table问题,@akrun的回答涵盖了这一问题,但为了完成

dplyr解决方案:

图书馆弹琴 dt%>%group_按年,quar%>%filtern==3 一个tibble:9x3 组:年,夸尔[3] 年度夸尔项目 1 1 1 1 2 1 1 2 3 1 1 3 4 1 4 1 5 1 4 2 6 1 4 3 7 2 1 1 8 2 1 2 9 2 1 3 基本上:

dt[avedt$item,dt[,cyear,quar],FUN=length==3,] 或


freqt使用join的另一个选项:

dt[dt[, .N, .(year, quar)][N==3], on=.(year, quar)]
编辑: 为了处理akrun注释,速度实际上取决于数据集的特征。以下是示例数据集的计时:

set.seed(0L)
ngrp <- 1e6
x <- sample(1:3, ngrp, TRUE)
dt <- data.table(year=rep(1:ngrp, times=x))[,
    quar:=year]

microbenchmark::microbenchmark(
    mtd0=dt[dt[, .I[.N == 3], .(year, quar)]$V1],
    mtd1=dt[dt[, .N, .(year, quar)][N==3], on=.(year, quar)],
    times=3L
)

使用联接的另一个选项:

dt[dt[, .N, .(year, quar)][N==3], on=.(year, quar)]
编辑: 为了处理akrun注释,速度实际上取决于数据集的特征。以下是示例数据集的计时:

set.seed(0L)
ngrp <- 1e6
x <- sample(1:3, ngrp, TRUE)
dt <- data.table(year=rep(1:ngrp, times=x))[,
    quar:=year]

microbenchmark::microbenchmark(
    mtd0=dt[dt[, .I[.N == 3], .(year, quar)]$V1],
    mtd1=dt[dt[, .N, .(year, quar)][N==3], on=.(year, quar)],
    times=3L
)

@akrun,它和我到目前为止管理的输出是一样的,减去I列。是不是就是项目columnexpectred@akrun,不,整个表减去i。这就是年、季度和项目。@akrun,它与我到目前为止管理的输出是相同的,减去I列。是项目column吗expectred@akrun,不,整个表减去i。这就是年度、季度和项目。是的,就是这样。由于某种原因,我记错了。我给出了每个分组子表中的行。dt[dt[,.I[.N==3],by=cyear,quar][,V1]]这将更通用一些。这部分我的意思是:[,V1]@M-M你可以使用$or[作为默认列名,这是肯定的。我的意思是,如果你想将V1作为参数传递,$V1将不起作用。正如我所说的,这是更通用的,而不是另一个是错误的。是的,就是这样。出于某种原因,我记错了。我给出了每个分组子表中的行。dt[dt[,I][N==3],by=cyear,quar][,V1]]这将是一个更通用的部分。这部分我的意思是:[,V1]@M-M你可以使用$or[作为默认列名,这是肯定的。我的意思是,如果您想将V1作为参数传递,$V1将不起作用。正如我所说,这是更通用的,而不是另一个列名是错误的。与IIs相比,它更快吗?与.I相比,它更快吗