R 的 duplicated返回一个向量,显示向量或数据帧的每个元素是否是下标较小的元素的副本。因此,如果5行数据帧中的3、4和5行是相同的,duplicated将给出向量
duplicated
FALSE, FALSE, FALSE, TRUE, TRUE
但在这种情况下,我实际上想得到
FALSE, FALSE, TRUE, TRUE, TRUE
也就是说,我想知道一行是否也被一个带有 更大下标的行复制。
您需要组装一组 duplicated值,应用 unique,然后使用 %in%进行测试。像往常一样,一个示例问题将使这个过程生动起来。
unique
%in%
> vec <- c("a", "b", "c","c","c") > vec[ duplicated(vec)] [1] "c" "c" > unique(vec[ duplicated(vec)]) [1] "c" > vec %in% unique(vec[ duplicated(vec)]) [1] FALSE FALSE TRUE TRUE TRUE
duplicated有一个 fromLast参数。?duplicated的“示例”部分向您展示了如何使用它。只需调用 duplicated两次,一次用 fromLast=FALSE,一次用 fromLast=TRUE,并取其中任一行为 TRUE。
fromLast
?duplicated
fromLast=FALSE
fromLast=TRUE
TRUE
编辑: 您没有提供一个可重复的示例,因此这里有@jbaums 提供的一个插图
vec <- c("a", "b", "c","c","c") vec[duplicated(vec) | duplicated(vec, fromLast=TRUE)] ## [1] "c" "c" "c"
编辑: 以数据框架为例:
df <- data.frame(rbind(c("a","a"),c("b","b"),c("c","c"),c("c","c"))) df[duplicated(df) | duplicated(df, fromLast=TRUE), ] ## X1 X2 ## 3 c c ## 4 c c
我已经有了 同样的问题,如果我没记错的话,这也是一个答案。
vec[col %in% vec[duplicated(vec$col),]$col]
不知道哪一个更快,但是,我目前使用的数据集不够大,不足以进行测试,产生重大的时间差。
如果您对某些列的哪些行是重复的感兴趣,您可以使用 皮尔方法:
ddply(df, .(col1, col2), function(df) if(nrow(df) > 1) df else c())
使用 Dplyr添加 count 变量:
df %>% add_count(col1, col2) %>% filter(n > 1) # data frame df %>% add_count(col1, col2) %>% select(n) > 1 # logical vector
对于重复的行(考虑所有列) :
df %>% group_by_all %>% add_tally %>% ungroup %>% filter(n > 1) df %>% group_by_all %>% add_tally %>% ungroup %>% select(n) > 1
这些方法的好处是,您可以指定多少个重复项作为截止值。
通过执行以下操作,可以使用 dplyr获得数据帧中的重复行
dplyr
library(tidyverse) df = bind_rows(iris, head(iris, 20)) # build some test data df %>% group_by_all() %>% filter(n()>1) %>% ungroup()
可以使用排除某些列 group_by_at(vars(-var1, -var2))来对数据进行分组。
group_by_at(vars(-var1, -var2))
如果实际上需要行索引而不仅仅是数据,那么您可以首先添加它们,如下所示:
df %>% add_rownames %>% group_by_at(vars(-rowname)) %>% filter(n()>1) %>% pull(rowname)
下面是@Joshua Ulrich 的函数解。这种格式允许您使用与重复()相同的方式来使用此代码:
allDuplicated <- function(vec){ front <- duplicated(vec) back <- duplicated(vec, fromLast = TRUE) all_dup <- front + back > 0 return(all_dup) }
用同样的例子:
vec <- c("a", "b", "c","c","c") allDuplicated(vec) [1] FALSE FALSE TRUE TRUE TRUE
我也遇到过类似的问题,但是我需要通过特定列中的值来识别重复的行。我想出了以下 Dplyr解决方案:
df <- df %>% group_by(Column1, Column2, Column3) %>% mutate(Duplicated = case_when(length(Column1)>1 ~ "Yes", TRUE ~ "No")) %>% ungroup()
代码按特定列对行进行分组。如果组的长度大于1,则代码将组中的所有行标记为重复。一旦这样做,你可以使用 Duplicated列过滤等。
Duplicated
这更新了@Holger Brandl 的回答,以反映最新版本的 dplyr (例如1.0.5) ,其中 group_by_all()和 group_by_at()已被取代。帮助文档建议使用 across()代替。
group_by_all()
group_by_at()
across()
因此,要获取所有有副本的行,您可以这样做: iris %>% group_by(across()) %>% filter(n() > 1) %>% ungroup()
iris %>% group_by(across()) %>% filter(n() > 1) %>% ungroup()
要包含这些行的索引,请添加一个“ rowid”列,但将其从分组中排除: iris %>% rowid_to_column() %>% group_by(across(!rowid)) %>% filter(n() > 1) %>% ungroup()
iris %>% rowid_to_column() %>% group_by(across(!rowid)) %>% filter(n() > 1) %>% ungroup()
在上面的后面追加 %>% pull(rowid),您将得到索引的向量。
%>% pull(rowid)
这就是 vctrs::vec_duplicate_detect()的工作原理
vctrs::vec_duplicate_detect()
# on a vector vctrs::vec_duplicate_detect(c(1, 2, 1)) #> [1] TRUE FALSE TRUE # on a data frame vctrs::vec_duplicate_detect(mtcars[c(1, 2, 1),]) #> [1] TRUE FALSE TRUE
由 Reprex 软件包于2022.07-19年度创作(v2.0.1)