计算2列中的不同值

时间:2019-08-29 20:33:28

标签: r

我只需要获取分散在两列中的不同值,然后将不同值返回到一列即可。 示例:

 colA colB
---- --------
darcy elizabeth
elizabeth darcy
jon doe
doe joe

它应该返回:

resultCol
darcy
elizabeth
jon
doe

是否有任何内置函数或库可以更有效地执行此操作?

我尝试了一种变通方法来获取结果,但是对于十万多个观察而言,它非常慢。

#First i create a sample dataframe
col1<-c("darcy","elizabeth","elizabeth","darcy","john","doe")
col2<-c("elizabeth","darcy","darcy","elizabeth","doe","john")

dfSample<-data.frame(col1,col2)

#Then i create an empty dataframe to store all values in a single column
emptyDataframe<-data.frame(resultColumn=character())

for(i in 1:nrow(dfSample)){
  emptyDataframe<-rbind(emptyDataframe,c(toString(dfSample[i,1])),stringsAsFactors=FALSE)
}

for(i in 1:nrow(dfSample)){
  emptyDataframe<-rbind(emptyDataframe,c(toString(dfSample[i,2])),stringsAsFactors=FALSE)
}

emptyDataframe

#Finally i get the distinct values using dplyr
var_distinct_values<-distinct(emptyDataframe)

2 个答案:

答案 0 :(得分:3)

我使用并集来获取特定列中的唯一值:

with(dfSample, union(col1,  col2))


PS: d.b注释中的答案也是另一种方式。

如果您有多余的列,但只想在特定的列上运行,则可以即兴回答:

unique(unlist(dfSample[1:2]))

这将从前两列获取唯一值。

答案 1 :(得分:1)

这是通用解决方案。
它基于this answer,但是只要对象是data.framelist,就可以扩展到任意数量的列。

Reduce(union, dfSample)
[1] "darcy"     "elizabeth" "john"      "doe"

现在每10列中有10万个观测值。

set.seed(1234)
n <- 1e5
bigger <- replicate(n, sample(c(col1, col2), 10, TRUE))
bigger <- as.data.frame(bigger)

system.time(Reduce(union, bigger))
#     user    system  ellapsed
#    3.769     0.000     3.772

编辑。

经过一番思考,我意识到上面的测试是在具有很少数量不同值的数据帧上运行的。数量更大的测试不一定能得到相同的结果。

set.seed(1234)
s <- sprintf("%05d", 1:5000)
big2 <- replicate(n, sample(s, 10, TRUE))
big2 <- as.data.frame(big2)
rm(s)

microbenchmark::microbenchmark(
  red = Reduce(union, big2),
  uniq = unique(unlist(big2)),
  times = 10
)
#Unit: seconds
# expr       min       lq      mean    median       uq       max neval cld
#  red 26.021855 26.42693 27.470746 27.198807 28.56720 29.022047    10   b
# uniq  1.405091  1.42978  1.632265  1.548753  1.56691  2.693431    10  a 

unique/unlist解决方案现在明显更好。