有的时候发现想找出有重复的数据,可能有不同的需求,就要有不同的解决办法了
先弄一个小点的数据作为例子:
> name <- c("a","b","a","a","c","c")
> num <- 1:6
> dt1 <- data.frame(name = name, number = num)
> dt1
name number
1 a 1
2 b 2
3 a 3
4 a 4
5 c 5
6 c 6
这里的name是有重复的,number没有重复。
1.去除重复数据
这里的重复,是指两行数据完全相同,也就是说dt1整体来说是没有重复的,只有name有重复。用基础包中的unique()函数可以做到去除完全重复的数据,所有的行只会出现一次:
> unique(dt1)
name number
1 a 1
2 b 2
3 a 3
4 a 4
5 c 5
6 c 6
> unique(dt1$name)
[1] "a" "b" "c"
那如果要选出某一列有重复的数据该怎么办呢?这就要借助一下另一个函数:duplicated()
2.选出重复了的数据
duplicated()函数返回的是和原数据长度相同的一组逻辑值,于是,可以用来判断和选择数据。找出有重复的,找出没有重复的都可以做到。
> duplicated(dt1$name)
[1] FALSE FALSE TRUE TRUE FALSE TRUE
> dt1[duplicated(dt1$name) == T,]
name number
3 a 3
4 a 4
6 c 6
> dt1[duplicated(dt1$name) == F,]
name number
1 a 1
2 b 2
5 c 5
这也要还有一个问题,它只会选择出第二次及其以后出现的数据,a在原数据中出现了三次,第一次上出现的a,它认为是没有重复的,如果也想选择出来该怎么做呢?我寻找到一个我觉得比较好的办法。
3.选出有重复的数据(包含第一次出现的)
这里使用了一个比较厉害的包了,dplyr,看来得好好学一学它。
> library(dplyr)
> duplicate_name = dt1 %>% group_by(name) %>% summarise(freq = n()) %>% filter(freq > 1) %>% select(name)
> duplicate_name
# A tibble: 2 x 1
name
<chr>
1 a
2 c
> duplicate_data = dt1[dt1$name %in% duplicate_name$name, ]
> duplicate_data
name number
1 a 1
3 a 3
4 a 4
5 c 5
6 c 6
貌似这个包需要额外安装下。这里的%>%类似通道符,把左边的结果传输到右边,%%感觉有点转义符的意味了。
先是对频数进行记录,在来一轮选择,如果想知道每一步都发生了什么,可以一段一段拆解开来运行看一下。
最终,出现过重复的所有数据就都选择出来啦!
参考资料
番外
以及我看还有人是通过循环,再找一遍和重复数据有重合的,来弥补第一次数据的缺失,我感觉比较麻烦一些,而且数据比较大的话,貌似就不是太方便了,我也去试试看。
使用R语言筛选数据中的重复行
dt2 <- dt1[duplicated(dt1$name) == T,]
# 原始代码
for (i in c(1:nrow(dt2))){
for (j in c(1:nrow(dt1))){
if (sum(dt2[i,] == dt1[j,]) == ncol(dt1)){
print(dt1[j,])
print(paste( "In the row", j))
}
}
}
# 改进一下:
dt3 <- data.frame()
for (i in c(1:nrow(dt2))){
for (j in c(1:nrow(dt1))){
if (dt2[i,1] == dt1[j,1]) {
dt3 <- rbind(dt3,dt1[j,])
}
}
}
dt3
# 发现有重复,因为dt2中的a有出现两次
这个比较适用于完全一致的那种重复,而且不适合重复3次以上次的数据,我裂开了,有兴趣可以看看原文章,我个人还是觉得dplyr包好使,又快又准。
就到这啦!对你有帮助就点个赞叭!