Find uniqueness in data frame withe rows NA?

柔情痞子 提交于 2021-02-16 08:54:51

问题


I have a data frame like below. I would like to find unique rows (uniqueness). But in this data I have 'NA'. I like if all value in one row with NA value is the same with other rows (like rows: 1,2,5) I want to ignore it, but if not same (like rows : 2,4) I like to keep it as unique row. For example, in rows 1 ,2 and 6 all values except NA are the same so because NA can be value '1 and 3' I like to remove this row and just keep row 2. Also, in row 6 values 2 and 3 (exclude NA) are the same as row c2 and c5 and there is possible NAs in c6 get same value like as c2 and c5, so this row is not unique.

Also, @ Sotos solution help me more but in last part after removing NA when make pattern for rows , his solution consider same pattern (23) for c8 and c6 and remove them. But actually c8 is unique.

data:

      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

I would like to have this output:

output:

     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:


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

Testing the code with the additional row as per your comment:

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

DATA

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"))



回答2:


My solution would be to :

1) Take all unique solutions in row that do not have a NA.

2) Among those that have NAs, see if the rest of the values is identical to another row

Reproduce data

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))

Create two unique data frames (one with NAs, the other without

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,])

Add rows from NAs matching your condition

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)
  }

}


来源:https://stackoverflow.com/questions/36327084/find-uniqueness-in-data-frame-withe-rows-na

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!