按行和列互易子集

时间:2017-09-05 15:29:16

标签: r duplicates

我无法根据行和列中值的互易性对data.frame进行子集化。

以下是用于说明问题的示例:

rater <- c(21, 23, 26, 24)
ratee <- c(24, 21, 23, 21)
rating.data <- data.frame(rater, ratee)

输出:

   rater ratee
1    21    24
2    23    21
3    26    23
4    24    21

我想通过仅保留具有倒数值的行来对此df进行子集化。

结果子集应如下所示:

   rater ratee
1    21    24
4    24    21

任何想法都将不胜感激!

5 个答案:

答案 0 :(得分:10)

我们可以按行排序,然后使用duplicated

m1 <- t(apply(rating.data, 1, sort))
rating.data[duplicated(m1)|duplicated(m1, fromLast = TRUE),]
#   rater ratee
#1    21    24
#4    24    21

答案 1 :(得分:6)

另一种可能性:

library(dplyr)
rating.data %>% inner_join(.,.,by=c("rater" = "ratee","ratee"="rater"))

或者这个,由于某些原因,它在你的小例子上快两倍(虽然比akrun的解决方案慢):

merge(rating.data,setNames(rating.data,rev(names(rating.data))))

使用其他列保持第二种解决方案的灵活性:

merge(rating.data,setNames(rating.data[,c("rater","ratee")],c("ratee","rater")))

答案 2 :(得分:2)

library(data.table)
N=10#number of rows 
dt1<-data.table(a=1:N,b=sample(N))#create the data.table that holds the info

dt1[,d:=ifelse(a<b,paste0(a,"_",b),paste0(b,"_",a))]#create unique key per pair  respecting the rule "min_max"
setkey(dt1,d)#setting the key 
dt1[dt1[,.N,d][N!=1],.(a,b)] #keep only the pairs that appear more than once

答案 3 :(得分:2)

您还可以使用pminpmax来协助分组,然后对具有多个条目的所有群组进行过滤,即

library(dplyr)

df %>% 
 group_by(grp = paste0(pmin(rater, ratee), pmax(rater, ratee))) %>% 
 filter(n() > 1) %>% 
 ungroup() %>% 
 select(-grp)

给出,

# A tibble: 2 x 2
  rater ratee
  <dbl> <dbl>
1    21    24
2    24    21

答案 4 :(得分:1)

在精神上与akrun的方法类似,rbind data.frame与副本相反的副本。从底部开始查找重复项,然后对原始data.frame中的行返回TRUE。使用[seq_len(nrow(rating.data))]将此逻辑向量子集化,以将适当长度的向量返回到[,以便在行上进行子集化。

rating.data[duplicated(rbind(rating.data,
                             unname(unclass(rating.data[2:1]))),
                       fromLast=TRUE)[seq_len(nrow(rating.data))],]
  rater ratee
1    21    24
4    24    21