Malna
Malna

Reputation: 59

How can I identify duplicated elements in rows

I have a data frame which looks like this but with altogether 31 variables(columns) and 11000 observations (the missing values are empty):

T1 = c("a1", "c1", "e1", "d1", "a3", "f1", "f2") 
T2 = c("b1", "d1", "a1", "b2", "a3", "f1", "f3")
T3 = c(NA, NA, "e1", "d1", NA, "a4", "f3")
T4 = c( NA, NA, NA, "b2", NA, "b3", "f5")
T5 = c( NA, NA, NA, NA, NA, "a4", "f6")
T6 = c( NA, NA, NA, NA, NA,  NA, "f7") 
T7 = c(NA, NA, NA, NA, NA, NA, "c1")
T8 = c(NA, NA, NA, NA, NA, NA, "c1")
T9 = c(NA, NA, NA, NA, NA, NA, "f2")
T10= c(NA, NA, NA, NA, NA, NA, "f3")

I would like to identify if there is any duplicated element of the "T" type variables by rows, so my df would look like this:

 T1 = c("a1", "c1", "e1", "d1", "a3", "f1", "f2") 
 T2 = c("b1", "d1", "a1", "b2", "a3", "f1", "f3")
 T3 = c(NA, NA, "e1", "d1", NA, "a4", "f3")
 T4 = c( NA, NA, NA, b2, NA, "b3", "f5")
 T5 = c( NA, NA, NA, NA, NA, "a4", "f6")
 T6 = c( NA, NA, NA, NA, NA,  NA, "f7") 
 T7 = c(NA, NA, NA, NA, NA, NA, "c1")
 T8 = c(NA, NA, NA, NA, NA, NA, "c1")
 T9 = c(NA, NA, NA, NA, NA, NA, "f2")
 T10= c(NA, NA, NA, NA, NA, NA, "f3")
 D = c(F, F, T, T, T, T, T)

I attempted to write a function but clearly I miss something because it does not work: first I created a new variable with empty values

df$D <- ""

then the function:

dupl <- function(x){
     for(i in 1:nrow(x))
              if (duplicated(x[i], incomparables = NA)){
            df$D <- "TRUE"
  }else{
    df$D <- "FALSE"
  }
}

df$D <- dupl(df)

I also tried this code but it does not give me the rows (when D takes a value of true) which contains the duplicated elements:

df$D <- apply(df[-1], 1, function(i) any(duplicated(i, incomparables = NA)))

Upvotes: 1

Views: 61

Answers (2)

akash87
akash87

Reputation: 3994

I'm a fan of dplyr and tidyverse which is why I would go this route:

df <- data.frame(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)

df %>% 
mutate(index = row_number()) %>% 
gather(key, value, -index, na.rm = T) %>% 
group_by(index) %>% 
summarise(D = any(duplicated(value))) %>%
cbind(df)

Upvotes: 0

Rui Barradas
Rui Barradas

Reputation: 76402

The following uses base R only.

df1$D <- apply(df1, 1, function(x) {
  x <- na.omit(x)
  any(unlist(Map('==', x[1], x[-1])))
})

df1
#  T1 T2   T3   T4   T5   T6   T7   T8   T9  T10     D
#1 a1 b1 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> FALSE
#2 c1 d1 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> FALSE
#3 e1 a1   e1 <NA> <NA> <NA> <NA> <NA> <NA> <NA>  TRUE
#4 d1 b2   d1   b2 <NA> <NA> <NA> <NA> <NA> <NA>  TRUE
#5 a3 a3 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>  TRUE
#6 f1 f1   a4   b3   a4 <NA> <NA> <NA> <NA> <NA>  TRUE
#7 f2 f3   f3   f5   f6   f7   c1   c1   f2   f3  TRUE

Data.

With the vectors in the question, the data.frame is created with the following code. It uses a function from external package stringr.

v <- stringr::str_sort(ls(pattern = '^T[[:digit:]]+$'), numeric = TRUE)
df1 <- data.frame(mget(v))

Upvotes: 1

Related Questions