删除R或SQL中最不完整的重复行

时间:2017-05-26 16:58:45

标签: sql r duplicates

我有这样的数据集:

id_1 <- c(1, 1, 1)
id_2 <- c(2, NA, NA)
day <- c("Mon", "Mon", "Mon")
month <- c("May", NA, "May")
year <- c("2017", NA, NA)

df <- cbind(id_1, id_2, day, month, year)

这些行是我数据中的重复观察。我想只保留最完整的行(即第1行)。我的真实数据有15列,所以使用

duplicated(df[, <some combination of columns>])

似乎很复杂。这有功能吗?还是我忽略了一些简单的答案? R中的答案是首选,但SQL也是可能的。提前谢谢!

编辑: id_1和id_2都是观察的标识符。 id_1在这个数据中肯定是唯一的,但是对于某些行,id_2可以是NA或重复。最后,我将使用id_2将此数据表与另一个数据表合并。这就是为什么我想要删除重复包含id_2的行所捕获的信息的行。

3 个答案:

答案 0 :(得分:4)

如果id_1是每个&#34;主题&#34;的标识符,那么您可以这样做:

library(tidyverse)

df %>% 
  group_by(id_1) %>%
  filter(rowSums(is.na(.)) == min(rowSums(is.na(.))))

您是否有两行具有相同数量的缺失值,但每行中缺少不同的值?在这种情况下,您可能希望组合来自不同行的数据以创建包含所有可用数据的单个行。

更新:根据@ docendodiscimus的评论,您可以按如下方式缩短代码:

df %>% 
  group_by(id_1) %>%
  slice(which.min(rowSums(is.na(.))))

答案 1 :(得分:1)

eipi10的解决方案当然看起来更整洁,但这个是基础R。

 df[     apply(df, 1, function(x) length(na.omit(x))) == 
    max( apply(df, 1, function(x) length(na.omit(x))) )
        ,  ]
 #---------------- 
  id_1   id_2    day  month   year 
   "1"    "2"  "Mon"  "May" "2017" 

你没有说这应该在相同id1的组中完成,但是如果你这样做,那么eipi10的group_by将对应于一个基础lapply( split(df, df$id1) , ...function)。我喜欢@MikeH。建议使用rowSums(!is.na(df))比我的想法更好。也许他会发一个答案?

答案 2 :(得分:0)

如果初始数据集是data.frame,我们也可以尝试使用Reduce中的data.table

library(data.table)
setDT(df)[, .SD[which.min(Reduce(`+`, lapply(.SD, is.na)))], id_1]
#   id_1 id_2 day month year
#1:    1    2 Mon   May 2017

数据

df <- data.frame(id_1, id_2, day, month, year, stringsAsFactors=FALSE)