列中值的重复组合

时间:2015-09-01 10:29:56

标签: r dataframe

this question类似,我有一个数据框,并希望提取在几个特定列中的值组合中不唯一的行。

例如,我有一个数据框df:

> df<-data.frame(c(1,2,3,4),c(T,F,T,T),c("a","b","c","b"),c("b","d","e","a"))
> df
     [,1] [,2]    [,3] [,4]
[1,] "1"  "TRUE"  "a"  "b" 
[2,] "2"  "FALSE" "b"  "d" 
[3,] "3"  "TRUE"  "c"  "e" 
[4,] "4"  "TRUE"  "b"  "a" 

我想测试数据框2,3和4中值的组合对于数据帧的行是唯一的还是重复的。但是,我不想将组合的第一次出现分类为唯一,所有后续组合都是重复,而是所有出现的非唯一组合重复

在此示例中,第1行和第4行是重复的,第2行和第3行在第2,3和4列的值组合中是唯一的。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

使用dplyr的替代方法。它使用行的所有组合并检查一行的所有元素是否属于另一行。在最后而不是True / False中,您会得到每行的数字,表示找到与其他行匹配的次数。如果你一步一步地运行脚本会更加明显。

df<-data.frame(x1 =c(1,2,3,4),
               x2 = c(T,F,T,T),
               x3 = c("a","b","c","b"),
               x4 = c("b","d","e","a"), stringsAsFactors = F)

library(dplyr)


df %>%                                                                                
  rowwise() %>%                                                                     # for each row
  do(data.frame(., df2=df, stringsAsFactors=F)) %>%                                 # combine each row with all rows of dataset
  filter(x1 != df2.x1) %>%                                                          # exclude cases of self combinations
  rowwise() %>%                                                                     # for each row combination
  mutate(match = 
           ifelse(sum(c(x2,x3,x4) %in% c(df2.x2, df2.x3, df2.x4))==3, 1, 0)) %>%    # flag a match when all 3 elements of one row belong to the elements of the other row 
  group_by(x1,x2,x3,x4) %>%                                                         # group by rows of initial dataset
  summarise(sum_match = sum(match)) %>%                                             # calculate how many times they match with other rows
  ungroup


#   x1    x2 x3 x4 sum_match
# 1  1  TRUE  a  b         1
# 2  2 FALSE  b  d         0
# 3  3  TRUE  c  e         0
# 4  4  TRUE  b  a         1

答案 1 :(得分:0)

我们sort&lt; df&#39;中的列3:4逐行使用applyMARGIN=1,转置(t)并将输出分配给相应的列。要获取所有重复项的逻辑索引,我们可以使用duplicated在默认方向和反方向应用fromLast=TRUE。在这里,我假设第一列不会用于考虑重复元素。

df[3:4] <- t(apply(df[3:4], 1, sort))
duplicated(df[-1])|duplicated(df[-1], fromLast=TRUE)
#[1]  TRUE FALSE FALSE  TRUE