R:按组,检查是否对于一个var的每个唯一值,至少有一个观察值,其中var的值等于另一个var的值

时间:2014-10-20 12:49:22

标签: r data.table

我认为我使用此代码的方向正确,但我还没到那里。

我尝试在Google和SE上找到有用的东西,但我似乎无法以一种能让我得到我想要的答案的方式来表达问题。

可以为此编写一个 for循环,比较每个 id 以及每个 a 的唯一值每行,但我努力实现更高水平的R理解,因此希望避免循环。

id <- c(1,1,1,2,2,2,3,3,3,4,4,4,5,5,5)
a <- c(1,1,1,2,2,2,3,3,4,4,4,5,5,5,6)
b <- c(1,2,3,3,3,4,3,4,5,4,4,5,6,7,8)

require(data.table)
dt <- data.table(id, a, b)

dt
dt[,unique(a) %in% b, by=id]
tmp <- dt[,unique(a) %in% b, by=id]
tmp$id[tmp$V1 == FALSE]

在我的示例中, ID 2,3和5应该是结果,决策规则是:“通过 id ,检查是否为 a 如果至少有一个观察值 b 的值等于 a 的值。“

但是,我的代码只输出 ID 2和5,但不输出3.这是因为对于 ID 3, 4 匹配使用之前观察的 4

结果应该输出不满足条件的ID,或者在原始表中添加一个虚拟变量,指示ID是否满足条件。

2 个答案:

答案 0 :(得分:2)

怎么样

dt[, all(sapply(unique(a), function(i) any(a == i & b == i))), by = id]

#   id    V1
#1:  1  TRUE
#2:  2 FALSE
#3:  3 FALSE
#4:  4  TRUE
#5:  5 FALSE

如果要在原始表中添加虚拟变量,可以像

一样进行修改
dt[, check:=all(sapply(unique(a), function(i) any(a == i & b == i))), by = id]

答案 1 :(得分:1)

我想知道我是否可以使用版本1.9.6中引入data.table的增强联接功能(在CRAN上)为这个旧问题找到更多 data.table-esk 解决方案2015年9月19日)。使用该版本,data.table已经获得了加入的能力,而无需使用on参数设置密钥。

变式1

dt[a == b][dt[, unique(a), by = id], on = .(id, a == V1)][is.na(b), unique(id)]
[1] 2 3 5

首先,选择dta相等的b行。对于每个a,只有这些行与id的唯一值正确连接。连接的结果是

dt[a == b][dt[, unique(a), by = id], on = .(id, a == V1)]
   id a  b
1:  1 1  1
2:  2 2 NA
3:  3 3  3
4:  3 4 NA
5:  4 4  4
6:  4 4  4
7:  4 5  5
8:  5 5 NA
9:  5 6 NA

NA中的b值表示未找到匹配项。具有id值的任何NA表示不满足OP的条件。

变式2

dt[dt[, unique(a), by = id], on = .(id, a == V1, b == V1), unique(id[is.na(x.a)])]
[1] 2 3 5

此版本权限加入dt(未经过滤!),每个a的唯一值为id,但加入条件需要id中的匹配以及匹配ab。 (这类似konvas' accepted answer中的a == i & b == i表达式。最后,返回那些id s,其中连接结果中至少有一个NA值表示缺少匹配。