我只需要获取分散在两列中的不同值,然后将不同值返回到一列即可。 示例:
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)
答案 0 :(得分:3)
我使用并集来获取特定列中的唯一值:
with(dfSample, union(col1, col2))
如果您有多余的列,但只想在特定的列上运行,则可以即兴回答:
unique(unlist(dfSample[1:2]))
这将从前两列获取唯一值。
答案 1 :(得分:1)
这是通用解决方案。
它基于this answer,但是只要对象是data.frame
或list
,就可以扩展到任意数量的列。
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
解决方案现在明显更好。