在以下data.df中,我们看到第2行和第3行是相同的,只是第4行的均值不同。
iso3 dest code year uv mean
1 ALB AUT 490700 2002 14027.2433 427387.640
2 ALB BGR 490700 2002 1215.5613 11886.494
3 ALB BGR 490700 2002 1215.5613 11886.494
4 ALB BGR 490700 2002 1215.5613 58069.405
5 ALB BGR 843050 2002 677.9827 4272.176
6 ALB BGR 851030 2002 31004.0946 32364.379
7 ALB HRV 392329 2002 1410.0072 6970.930
是否有任何简单的方法来自动查找这些相同的行? 我发现this subject似乎可以回答这个问题,但是我不明白'duplicated()`是如何工作的...
我想要的是一个“简单”的命令,在这里我可以精确地确定每行的列值应该相同。
类似于:function(data.df, c(iso3, dest, code, year, uv, mean))
查找相同的行,function(data.df, c(iso3, dest, code, year, uv))
查找“准”相同的行...
在第一种情况下,预期结果类似于:
2 ALB BGR 490700 2002 1215.5613 11886.494
3 ALB BGR 490700 2002 1215.5613 11886.494
以及第二个:
2 ALB BGR 490700 2002 1215.5613 11886.494
3 ALB BGR 490700 2002 1215.5613 11886.494
4 ALB BGR 490700 2002 1215.5613 58069.405
有什么主意吗?
答案 0 :(得分:3)
我们可以编写一个函数,然后传递我们要考虑的列。
get_duplicated_rows <- function(df, cols) {
df[duplicated(df[cols]) | duplicated(df[cols], fromLast = TRUE), ]
}
get_duplicated_rows(df, c("iso3", "dest", "code", "year", "uv","mean"))
# iso3 dest code year uv mean
#2 ALB BGR 490700 2002 1215.6 11886
#3 ALB BGR 490700 2002 1215.6 11886
get_duplicated_rows(df, c("iso3", "dest", "code", "year", "uv"))
# iso3 dest code year uv mean
#2 ALB BGR 490700 2002 1215.6 11886
#3 ALB BGR 490700 2002 1215.6 11886
#4 ALB BGR 490700 2002 1215.6 58069
答案 1 :(得分:1)
如果逐个查看每个要素,然后考虑行总和大于目标值的行,就可以得到准重复。
toread <- " iso3 dest code year uv mean
ALB AUT 490700 2002 14027.2433 427387.640
ALB BGR 490700 2002 1215.5613 11886.494
ALB BGR 490700 2002 1215.5613 11886.494
ALB BGR 490700 2002 1215.5613 58069.405
ALB BGR 843050 2002 677.9827 4272.176
ALB BGR 851030 2002 31004.0946 32364.379
ALB HRV 392329 2002 1410.0072 6970.930"
df <- read.table(textConnection(toread), header = TRUE)
closeAllConnections()
get_quasi_duplicated_rows <- function(df, cols, cut){
result <- matrix(nrow = nrow(df), ncol = length(cols))
colnames(result) <- cols
for(col in cols){
dup <- duplicated(df[col]) | duplicated(df[col], fromLast = TRUE)
result[ , col] <- dup
}
return(df[which(rowSums(result) > cut), ])
}
get_quasi_duplicated_rows(df, c("iso3", "dest", "code", "year", "uv","mean"), 4)
iso3 dest code year uv mean
2 ALB BGR 490700 2002 1215.561 11886.49
3 ALB BGR 490700 2002 1215.561 11886.49
4 ALB BGR 490700 2002 1215.561 58069.40
答案 2 :(得分:1)
使用dplyr
和rlang
包,我们可以实现这一目标-
解决方案-
find_dupes <- function(df,cols){
df <- df %>% get_dupes(!!!rlang::syms(cols))
return(df)
}
输出-
第一种情况-
> cols
[1] "iso3" "dest" "code" "year" "uv"
> find_dupes(df, cols)
# A tibble: 3 x 7
iso3 dest code year uv dupe_count mean
<fct> <fct> <int> <int> <dbl> <int> <dbl>
1 ALB BGR 490700 2002 1216. 3 11886.
2 ALB BGR 490700 2002 1216. 3 11886.
3 ALB BGR 490700 2002 1216. 3 58069.
第二例-
> cols
[1] "iso3" "dest" "code" "year" "uv" "mean"
> find_dupes(df,cols)
# A tibble: 2 x 7
iso3 dest code year uv mean dupe_count
<fct> <fct> <int> <int> <dbl> <dbl> <int>
1 ALB BGR 490700 2002 1216. 11886. 2
2 ALB BGR 490700 2002 1216. 11886. 2
注意-
rlan::syms
函数将字符串作为输入并将其转换为符号。与as.name()相反,它们事先将字符串转换为本地编码。这是必需的,因为符号会默默地删除字符串的编码标记。
要在dplyr
函数中传递矢量名称列表,我们使用syms
。
!!!
用于取消报价
答案 3 :(得分:1)
我们可以使用group_by_all
来过滤频率计数超过1的
library(dplyr)
df1 %>%
group_by_all() %>%
filter(n() > 1)
# A tibble: 2 x 6
# Groups: iso3, dest, code, year, uv, mean [1]
# iso3 dest code year uv mean
# <chr> <chr> <int> <int> <dbl> <dbl>
#1 ALB BGR 490700 2002 1216. 11886.
#2 ALB BGR 490700 2002 1216. 11886.
如果它是列的子集,请使用group_by_at
df1 %>%
group_by_at(vars(iso3, dest, code, year, uv)) %>%
filter(n() > 1)
# A tibble: 3 x 6
# Groups: iso3, dest, code, year, uv [1]
# iso3 dest code year uv mean
# <chr> <chr> <int> <int> <dbl> <dbl>
#1 ALB BGR 490700 2002 1216. 11886.
#2 ALB BGR 490700 2002 1216. 11886.
#3 ALB BGR 490700 2002 1216. 58069.