我正在研究一个有两个分组变量和一个值的问题。我只是保持行的值至少是组中的两个值彼此接近。在示例中,我希望组中的一组值彼此之间不超过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
答案 0 :(得分:4)
您可以将.I
与if
一起使用,以确定是否包括每个组(此处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)