R将unique()与逻辑条件组合以子集data.table

R将unique()与逻辑条件组合以子集data.table,r,conditional,data.table,unique,subset,R,Conditional,Data.table,Unique,Subset,我使用的是数据表1.9.6和R3.2.1 我有一个data.table,它有一个名为pid的键。具有相同pid的多个记录的完整性水平、采样日期和执行的测试类型不同。我需要将此data.table与pid上的另一个data.table合并,但是第二个表对于每个pid只有一条唯一的记录 因此,在合并之前,我需要对第一个data.table进行子集设置,以便每个pid只包含一条唯一的记录。我可以用unique()实现这一点,但这将按顺序为每个pid提供第一条记录,而这不一定是我想要的记录。对于每个pi

我使用的是数据表1.9.6和R3.2.1

我有一个data.table,它有一个名为pid的键。具有相同pid的多个记录的完整性水平、采样日期和执行的测试类型不同。我需要将此data.table与pid上的另一个data.table合并,但是第二个表对于每个pid只有一条唯一的记录

因此,在合并之前,我需要对第一个data.table进行子集设置,以便每个pid只包含一条唯一的记录。我可以用unique()实现这一点,但这将按顺序为每个pid提供第一条记录,而这不一定是我想要的记录。对于每个pid,我要查找包含特定测试类型(x)的行,该行具有该pid的最早样本日期,如果有多个pid具有最早样本日期,则其中具有最完整字段的行作为平局断路器

简单地按样本日期(从最小到最大)和完整字段的数量(从最大到最小)排序,然后应用unique()可以部分地解决问题,但有效地引用
test==“x”
条件是我遇到的问题

如何有效地消除data.table的重复,并基于满足特定逻辑条件(给定pid的所有行都可以根据这些逻辑条件进行计算)的行显式选择要保留的行

以下是一些示例数据:

pid <- c("a1", "b1", "c1", "a1", "c1", "c1", "c1")
sampledate <- c("2014-11-19", "2014-11-01", "2014-11-05", "2014-11-17", "2014-11-05", "2014-11-05", "2014-11-05")
age <- c(10,43,2,10,2,NA,2)
sex <- c("female","female","male","female","male",NA,"male")
test <- c("x", "x", "e", "x", "d", "y", "x")

dt <- data.table(cbind(pid,sampledate,age,sex,test))
dt[, sampledate := as.Date(sampledate)]
dt[, completefields := rowSums(!is.na(dt))]
在上面的输出中,对于pid“c1”,选择了测试“e”的记录,而我只对测试“x”的记录感兴趣。在顺序列表中包含test对我没有帮助,因为选项是d、e、x和y,其值是我想要的,“x”分别位于第三(如果按升序排列)或第二(如果按降序排列)位置

如果我将逻辑测试的结果添加到我的数据集中,我可以按顺序包括“testisx”列,并获得我想要的结果:

dt[, testisx := test=="x"]

setkey(dt, pid)
setorder(dt, pid, sampledate, -testisx, -completefields, na.last=TRUE)
dts=unique(dt)

 > dts
   pid sampledate age    sex test completefields testisx
1:  a1 2014-11-17  10 female    x              5    TRUE
2:  b1 2014-11-01  43 female    x              5    TRUE
3:  c1 2014-11-05   2   male    x              5    TRUE
这对于小数据集来说很好,但是为更大的数据集创建额外的列在计算上很昂贵


是否有任何方法可以为满足上述条件的每个pid选择一行,而无需创建额外的列?我不必使用unique();我可以构建一个forloop,但在构建之前,我想检查是否有更直接的方法

同一帮助页面
?unique.data.table
描述了可用于逻辑子集设置的
重复的
。不过,我认为你误解了逻辑表达式是如何构造的
max(x)
是一个数字,不是真/假值;可能你想使用
x==max(x)
。谢谢Frank,我选择的示例可能不是正确的,因为我对无法排序的逻辑表达式感兴趣(所以不是max和min,而是更多我在最后添加的testtype==“x”场景)。
dt1=dt[,.SD[unique(dt)&min(sampledate)&max(completefields)],by=pid]中的语法可能是错误的(如果sampledate的某个特定值等于sampledate的最小值(通过pid),我可以创建一个列来指示true/false,但在使用.SD时我还是有点新手)@Arun:我已经用一个更清晰的例子更新了我的问题,并使用了setorder,见上文。重复;如果我理解正确,此函数仍将仅将每条记录的第一条标记为非重复。仔细考虑后,我将我的问题归类为重复数据消除问题,但我承认unique()和duplicated()并不是按我所希望的方式设计的(尽管IMO添加可选条件以消除重复将是一个非常有用的补充)。
dt[, testisx := test=="x"]

setkey(dt, pid)
setorder(dt, pid, sampledate, -testisx, -completefields, na.last=TRUE)
dts=unique(dt)

 > dts
   pid sampledate age    sex test completefields testisx
1:  a1 2014-11-17  10 female    x              5    TRUE
2:  b1 2014-11-01  43 female    x              5    TRUE
3:  c1 2014-11-05   2   male    x              5    TRUE