标题变得更复杂了,我敢肯定,如果我能想到一种更好地描述它的方法,我会用Google更好地描述它。
我有如下数据:
SET ID
100301006 1287025
100301006 1287026
100301010 1287027
100301013 1287030
100301011 1287027
,我想识别并选择那些行中的每个值在该列中都具有唯一值的那些行。在上面的示例中,我只想抓取行:
100301013 1287030
我不希望SET
100301006
,因为它与ID字段中的2个不同记录(1287025
和1287026
)匹配。同样,我也不想SET 100301010
,因为它与(ID
)匹配的1287027
记录也可以匹配另一个SET(10030011
)。
在某些情况下,可能有超过2个匹配项。
我可以循环执行此操作,但这似乎很简单。我很喜欢基本的R或data.table解决方案,但是我对dplyr不太感兴趣(试图使依赖性最小化)。
答案 0 :(得分:3)
这是一个快速的base-R hack:
df <- read.table(header = TRUE, stringsAsFactors = FALSE, text = "
SET ID
100301006 1287025
100301006 1287026
100301010 1287027
100301013 1287030
100301011 1287027")
counts <- sapply(df, function(x) { tb <- table(x); tb[ match(x, names(tb)) ]; })
counts
# SET ID
# 100301006 2 1
# 100301006 2 1
# 100301010 1 2
# 100301013 1 1
# 100301011 1 2
在这一点上,我们具有在其列中找到每个元素的次数...,因此我们希望所有计数均为1的行。
df[ rowSums(counts == 1) == ncol(df), ]
# SET ID
# 4 100301013 1287030
答案 1 :(得分:3)
我们可以在每列上独立使用duplicated
来创建逻辑list
的{{1}},vector
到Reduce
到单个向量并使用用来对数据集的行进行子集
&
或者按照@ chinsoon12的建议
df1[Reduce(`&`, lapply(df1, function(x)
!(duplicated(x)|duplicated(x, fromLast = TRUE)))),]
# SET ID
#4 100301013 1287030
m1 <- sapply(df1, function(x) !(duplicated(x)| duplicated(x, fromLast = TRUE)))
df1[rowSums(m1) == ncol(m1),, drop = FALSE]
答案 2 :(得分:1)
使用base R
,也许您可以使用ave()
来做到:
r <-df[which(with(df,ave(seq(nrow(df)),SET,FUN = length)*ave(seq(nrow(df)),ID,FUN = length)) == 1),]
> r
SET ID
4 100301013 1287030
数据
df <- read.table(text="SET ID
100301006 1287025
100301006 1287026
100301010 1287027
100301013 1287030
100301011 1287027",header = T)
答案 3 :(得分:1)
您可以使用data.table仅选择具有1行的组,首先按ID分组,然后按SET分组。这类似于@ r2evans方法,用于检查ID和SET的计数是否均为1。
library(data.table)
setDT(df)
df[, if(.N == 1) .SD, ID][, if(.N == 1) .SD, SET]
# SET ID
# 1: 100301013 1287030
或超过2列
Reduce(function(x, y) x[, if(.N == 1) .SD, y], names(df), init = df)
# ID SET
# 1: 1287030 100301013