在含有NA行的数据框中找到唯一值?

3
我有一个数据框如下所示。我想找到唯一的行(独特性)。但在这个数据中,我有“NA”。如果一行中所有值与其他行相同(例如行1,2,5),我希望忽略它,但如果不同(例如行2,4),我希望将其保留为唯一的行。 例如,在第1、2和6行中,除了NA之外的所有值都相同,因此因为NA可以是值“1和3”,我希望删除此行并仅保留第2行。 此外,在第6行中,值2和3(不包括NA)与c2和c5行相同,并且c6中可能存在NAs,得到与c2和c5相同的值,因此此行不是唯一的。

此外,@ Sotos解决方案对我有更多帮助,但在最后一部分删除NA后,当为行制定模式时,他的解决方案认为c8和c6具有相同的模式(23)并将它们删除。但实际上c8是唯一的。

数据:

      a1  a2   a3   a4
c1    2    1    3   NA
c2    2    1    3    3
c3    2    1    4    3
c4    2    2    3   NA
c5    2    1    3    3
c6    2    NA   3   NA
c7    2    NA   0   NA
c8    2    3   NA   NA

我希望得到这个输出:
输出:
     a1    a2  a3   a4
c2    2    1    3    3
c3    2    1    4    3
c4    2    2    3   NA
c7    2    NA   0   NA
c8    2    3   NA   NA

1
那么在检查重复项时,NAs是通配符吗? - chinsoon12
2
你可以使用 hclust 来可视化相似性:plot(hclust(dist(your_data_frame))) - Mehrad Mahmoudian
Mehrad@ 感谢绘制此图,它是一张具有良好信息的漂亮图表。 - tob
2个回答

2
library(stringr) 
df <- unique(df)
#paste rows omitting NAs
df$new <- apply(df, 1, function(i) paste(na.omit(i), collapse = ''))
#use str_detect to determine whether each pattern is found more than once
df$new2 <- rowSums(sapply(df$new, function(i) str_detect(i, df$new)))
new_df <- subset(df, df$new2 == 1)
new_df <- new_df[, !names(new_df) %in% c('new', 'new2')]
new_df
#   V2 V3 V4 V5
#2  2  1  3  3
#3  2  1  4  3
#4  2  2  3 NA

根据您的评论,使用额外的行测试代码:

new_df
#   a1 a2 a3 a4
#c2  2  1  3  3
#c3  2  1  4  3
#c4  2  2  3 NA
#c7  2 NA  0 NA

数据

dput(df)
structure(list(a1 = c(2L, 2L, 2L, 2L, 2L, 2L, 2L), a2 = c(1L, 
1L, 1L, 2L, 1L, NA, NA), a3 = c(3L, 3L, 4L, 3L, 3L, 3L, 0L), 
    a4 = c(NA, 3L, 3L, NA, 3L, NA, NA)), .Names = c("a1", "a2", 
"a3", "a4"), class = "data.frame", row.names = c("c1", "c2", 
"c3", "c4", "c5", "c6", "c7"))

@tob,我已经添加了我使用的数据。请使用我使用的数据进行尝试,并让我知道发生了什么。 - Sotos
顺便说一下,我稍微编辑了代码,所以请重新复制并粘贴它。 - Sotos
好的,我们可以处理NA索引,但我现在没有时间。 - Sotos
不,它看起来像 c2,因为值 2 和 3 与 c2 相同,并且 c6 中的 NA 值可以获得与 c2 相同的值。 - tob
好的,现在变得更加复杂了。你需要在问题中澄清这样的事情,并在示例中包括这些情况。 - Sotos
显示剩余4条评论

0
我的解决方案是:
1)获取行中所有没有NA的唯一解决方案。
2)在具有NA的解决方案中,查看其余值是否与另一行相同。

复制数据

df<-data.frame(V1 = rep(2,times = 6),
    V2 = c(1,1,1,2,1,NA),
    V3=c(3,3,4,3,3,3),
    V4=c(NA,3,3,NA,3,NA))

创建两个独特的数据框(一个包含NA,另一个不包含)。
df1<-unique(df[apply(df,MARGIN=1,FUN =function(z) sum(is.na(z)))==0,])
df2<-unique(df[apply(df,MARGIN=1,FUN =function(z) sum(is.na(z)))>0,])

根据条件添加匹配的NA行

for(i in 1:nrow(df2)){
  vec<-df2[i,] 
  w<-is.na(vec)
  if(nrow(merge(vec[!w],df1[,w]))>0){ ###I remove columns where you have NAs
    df1<-rbind(df1,vec)
  }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接