在R中使用dplyr条件语句移除特定重复行的问题求助
问题分析与解决方案
你的核心问题是对duplicated()的逻辑理解有误,导致过滤条件不符合需求:
- 第一个代码中
duplicated(id1) & duplicated(a1)是分别判断id1重复且a1重复,这和你要的「a1与id1的组合重复」完全不是一个逻辑,会误判很多情况。 - 第二个代码用
new_id组合是正确的方向,但duplicated(new_id)只会标记该组合第二次及以后出现的行。比如adam-a的第一行是var1=0,它是该组合的首次出现,duplicated()返回FALSE,所以你的过滤条件会保留这行,但你实际需要删掉它——因为该组合存在非0的其他行。
正确方法一:分组过滤(推荐)
通过group_by(a1, id1)按组合分组,然后针对每组做过滤:如果组内只有一行则保留;如果组内有多行,只保留var1≠0的行(也就是删掉重复组合里var1=0的行)。
library(dplyr) a1 <- c('adam', 'adam', 'adam', 'megan', 'megan', 'megan', 'jen', 'jen', 'jen') id1 <- c('a', 'a', 'b', 'a', 'b', 'b', 'a', 'b', 'c') var1 <- as.numeric(c('0', '3.2', '3', '2.2', '1.1', '0', '1.2', '2.4','3.1')) test_df <- data.frame(a1, id1, var1) # 分组过滤得到目标结果 test_df_clean <- test_df %>% group_by(a1, id1) %>% filter(n() == 1 | var1 != 0) %>% ungroup() print(test_df_clean)
运行结果:
# A tibble: 7 × 3 a1 id1 var1 <chr> <chr> <dbl> 1 adam a 3.2 2 adam b 3 3 megan a 2.2 4 megan b 1.1 5 jen a 1.2 6 jen b 2.4 7 jen c 3.1
正确方法二:用distinct()实现
先将同组合内的非0行排在前面,再用distinct()按a1+id1组合去重,保留第一行(也就是保留非0行,自动排除后续的0行):
test_df_clean2 <- test_df %>% arrange(a1, id1, desc(var1 != 0)) %>% # 非0行优先排在同组合最前面 distinct(a1, id1, .keep_all = TRUE) print(test_df_clean2)
这个方法也能得到和期望完全一致的结果。
内容的提问来源于stack exchange,提问作者DonnyDolio
相关产品推荐
相关产品推荐

