【问题标题】:data.table - keep first row per group OR based on conditiondata.table - 根据条件保留每组的第一行或
【发布时间】:2021-11-27 20:27:39
【问题描述】:

我想将 1st obs 保留在 group OR mpg >= 10 中。如果不从 .N 创建变量分组,我们有什么办法吗?

我正在寻找使用 data.table 包的解决方案。我在下面尝试过,但它期待 j 所以得到警告。

library(data.table)

x <- mtcars

setDT(x)

x[.N==1 | mpg >= 10,,by=carb]

【问题讨论】:

标签: r data.table


【解决方案1】:

我们可以使用.I 来获取用于子集的rowindex

 x[x[, .I[seq_len(.N) == 1|mpg >= 30], by = carb]$V1]
     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
 1: 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
 2: 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
 3: 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
 4: 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
 5: 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
 6: 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
 7: 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
 8: 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
 9: 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
10: 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8

【讨论】:

  • 只是为了测试它。我使用 mpg >= 50 并且我期望每组 1 行,因为它是 OR 条件,但它只显示 2 行。我正在寻找组中的第一行或 mpg >= 10 的任何其他行(即使它不是组中的第一行)
  • @R007 你是说要获取 mpg >= 10 的第一行,如果不存在,则获取第一行
  • @R007 请检查这是否是预期的输出
【解决方案2】:

试试这个。

使用mpg &gt;= 50,我们应该得到每carb一行:

x[ rowid(carb) == 1 | mpg >= 50,]
#      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
#    <num> <num> <num> <num> <num> <num> <num> <num> <num> <num> <num>
# 1:  21.0     6 160.0   110  3.90  2.62 16.46     0     1     4     4
# 2:  22.8     4 108.0    93  3.85  2.32 18.61     1     1     4     1
# 3:  18.7     8 360.0   175  3.15  3.44 17.02     0     0     3     2
# 4:  16.4     8 275.8   180  3.07  4.07 17.40     0     0     3     3
# 5:  19.7     6 145.0   175  3.62  2.77 15.50     0     1     5     6
# 6:  15.0     8 301.0   335  3.54  3.57 14.60     0     1     5     8

使用mpg &gt;= 30(自all(mpg &gt; 10)),我们应该得到以上所有以及更多:

x[ rowid(carb) == 1 | mpg >= 30,]
#       mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
#     <num> <num> <num> <num> <num> <num> <num> <num> <num> <num> <num>
#  1:  21.0     6 160.0   110  3.90 2.620 16.46     0     1     4     4
#  2:  22.8     4 108.0    93  3.85 2.320 18.61     1     1     4     1
#  3:  18.7     8 360.0   175  3.15 3.440 17.02     0     0     3     2
#  4:  16.4     8 275.8   180  3.07 4.070 17.40     0     0     3     3
#  5:  32.4     4  78.7    66  4.08 2.200 19.47     1     1     4     1
#  6:  30.4     4  75.7    52  4.93 1.615 18.52     1     1     4     2
#  7:  33.9     4  71.1    65  4.22 1.835 19.90     1     1     4     1
#  8:  30.4     4  95.1   113  3.77 1.513 16.90     1     1     5     2
#  9:  19.7     6 145.0   175  3.62 2.770 15.50     0     1     5     6
# 10:  15.0     8 301.0   335  3.54 3.570 14.60     0     1     5     8

另一种选择,以防您需要更多分组变量:

x[, .SD[seq_len(.N) == 1L | mpg >= 30,], by = carb]

虽然我被告知rowid(...)seq_len(.N) 更有效率。

【讨论】:

  • 另一种避免by 的方法是!duplicated。 (如果有更多分组变量,duplicated.data.table 有一个 by 参数`)
  • 好的,但我不知道查找重复行对这个过程有何帮助。您能否详细说明如何在过滤中使用它? @Henrik
  • 注意!。一组相同值中的第一行是“不重复”行,所有后续行都是重复的。
  • 好的,我想我明白你在说什么了。我想这将使它成为x[!duplicated(x, by="carb") | mpg &gt;= 30,]。这是一个有趣的替代方案,感谢您的澄清。
  • 我完全同意。重复的东西只是 rowid 部分的替代品。干杯
猜你喜欢
  • 1970-01-01
  • 2022-11-20
  • 2022-12-10
  • 2014-09-14
  • 2015-03-07
  • 1970-01-01
  • 1970-01-01
  • 2019-07-13
  • 2015-02-17
相关资源
最近更新 更多