寻找一种基于多变量组中值差异的更干净的方法来过滤数据表

时间:2019-08-15 15:48:39

标签: r data.table

我正在研究一个有两个分组变量和一个值的问题。我只是保持行的值至少是组中的两个值彼此接近。在示例中,我希望组中的一组值彼此之间不超过10。

下面是我最初尝试的方法,有关创建标志变量的某些操作使我感到自己正在以某种round回的方式进行操作,我只是想知道是否有更清洁的,更意图在数据中执行类似操作的方式。表。谢谢!

x和y是类别,z是值。

library(data.table)
set.seed(123)


dt <- data.table(
  x = sample(LETTERS, 1000, T),
  y = sample(letters, 1000, T),
  z = sample(100, 1000, T),
  key = tail(letters, 3)
)

dt <- unique(dt)
dt <- dt[dt[, .(flag = any(diff(z) <= 11)), .(x, y)], on = c("x", "y")][(flag)]
dt[, flag := NULL]
dt

2 个答案:

答案 0 :(得分:4)

您可以将.Iif一起使用,以确定是否包括每个组(此处want与您的最终dt相匹配)

dt <- unique(dt)
want <- dt[dt[, if(any(diff(z) <= 11)) .I, .(x, y)]$V1]

答案 1 :(得分:3)

你可以做

res <- dt[, if (.N > 1L && min(diff(z)) <= 11) .SD, by=.(x, y)]

我使用min代替了any,因为我猜它会导致更少的计算。

我添加了.N > 1L条件,因为您需要考虑如何处理单行情况(diff为NA)。您可以

  • .N > 1L &&删除这些案件
  • .N == 1L ||保留它们
  

我只是想知道在data.table中是否有更清洁的方法来执行类似的操作

我认为having=语法对此很方便。当前是a feature request


输入数据(因为OP覆盖了它):

library(data.table)
set.seed(123)
dt <- data.table(
  x = sample(LETTERS, 1000, T),
  y = sample(letters, 1000, T),
  z = sample(100, 1000, T),
  key = tail(letters, 3)
)
dt <- unique(dt)