我有两个消息ID,比如197,198。我想为那些从这些ID获取消息的用户分配数据框。我只想要那些包含这两个消息ID的行。
数据框为m
我使用过代码
a = c(197,198)
n = subset(m$userid,m$mid %in% a)
我也试过
n = m[m$mid == 197 & m$mid == 198]
这两个代码都在创建OR输出,而我想要AND输出。
这是样本数据框:
mid userid opened
197 1022 Y
197 1036 N
197 1100 Y
198 1000 Y
198 1022 N
198 1036 Y
我希望输出为包含197年和198年中期用户ID的记录
mid userid opened
197 1022 Y
197 1036 N
198 1022 N
198 1036 Y
答案 0 :(得分:1)
使用sqldf
一个解决方案可以实现:
# data
m <- read.table(text = "mid userid opened
197 1022 Y
197 1036 N
197 1100 Y
198 1000 Y
198 1022 N
198 1036 Y", header = T, stringsAsFactors = F)
library(sqldf)
result <- sqldf("SELECT * FROM m
WHERE userid in (SELECT userid FROM m WHERE mid == 197) AND
userid in (SELECT userid FROM m WHERE mid == 198)")
result
# mid userid opened
# 1 197 1022 Y
# 2 197 1036 N
# 3 198 1022 N
# 4 198 1036 Y
答案 1 :(得分:1)
使用重复:
m[duplicated(m$userid) | duplicated(m$userid,fromLast = T), ]
# mid userid opened
# 1 197 1022 Y
# 2 197 1036 N
# 5 198 1022 N
# 6 198 1036 Y
根据您的真实数据,您可能需要先:m2 <- subset(m,mid %in% a)
,以确保在应用我的解决方案之前,您的表中只有mid
a
。
答案 2 :(得分:0)
为了完整起见,这里有两个data.table
方法。两者都能够处理任意长度的a
,即只选择2个mid
。
library(data.table)
setDT(m)[m[mid %in% a][, uniqueN(mid), by = .(userid)][V1 == uniqueN(a)],
on = "userid"]
mid userid opened V1 1: 197 1022 Y 2 2: 198 1022 N 2 3: 197 1036 N 2 4: 198 1036 Y 2
表达式
m[mid %in% a][, uniqueN(mid), by = .(userid)][V1 == uniqueN(a)]
userid V1 1: 1022 2 2: 1036 2
过滤m
,然后按mid
计算唯一userid
的数量,并返回与userid
中所有条目匹配的a
。 (可以使用uniqueN(a)
而不是length(a)
,但前者更安全。
有一种替代方法可以返回m
的行ID,然后用于子集化:
m[mid %in% a][, .I[uniqueN(mid) == uniqueN(a)], by = .(userid)]
userid V1 1: 1022 1 2: 1022 5 3: 1036 2 4: 1036 6
m[m[mid %in% a][, .I[uniqueN(mid) == uniqueN(a)], by = .(userid)]$V1]
mid userid opened 1: 197 1022 Y 2: 198 1022 N 3: 197 1036 N 4: 198 1036 Y