使用R在不同的数据帧中分离重复的行

时间:2016-01-12 05:52:13

标签: r

我们说我有一个数据框df

df = data.frame(A=c(1,2,1,4,1,2,5,4),B=c(2,3,4,6,2,3,6,6))

如果我df[duplicated(df), ]我得到的只是重复的行。但我需要一个适用于每个数据帧的全局解决方案,并产生如下结果:

> dup1
   A B
 1 1 2 
 5 1 2

> dup2
   A B
 2 2 3
 6 2 3

> dup3
   A B
 4 4 6
 8 4 6

> others
   A B
 3 1 4
 7 5 6

3 个答案:

答案 0 :(得分:3)

我认为这会得到你想要的东西并更好地解决重复问题:

tmp <- df[do.call(order, df),]
out <- split(tmp, cumsum(!duplicated(tmp)))
others <- vapply(out, nrow, 1) == 1

c(
  setNames(out[!others],  paste0("dup", seq_len(sum(!others))) ),
  others=list(do.call(rbind, out[others]))
)

#$dup1
#  A B
#1 1 2
#5 1 2
#
#$dup2
#  A B
#2 2 3
#6 2 3
#
#$dup3
#  A B
#4 4 6
#8 4 6
#
#$others
#  A B
#3 3 4
#5 5 6

答案 1 :(得分:1)

您可以尝试使用duplicated函数查找重复的行并创建一个单独的组,

duplicated_rows <- df[duplicated(df) | duplicated(df, fromLast = TRUE) , ]
other_rows <- df[!(duplicated(df) | duplicated(df, fromLast = TRUE)) , ]

duplicated_rows
#  A B
#1 1 2
#2 2 3
#4 4 6
#5 1 2
#6 2 3
#8 4 6

other_rows
#  A B
#3 3 4
#7 5 6

要按排序顺序获取,可以使用order函数

duplicated_rows[order(duplicated_rows$A), ]

#  A B
#1 1 2
#5 1 2
#2 2 3
#6 2 3
#4 4 6
#8 4 6

此外,您可以使用split命令拆分行(如@akrun所述)

sorted_rows <- duplicated_rows[order(duplicated_rows$A), ]
split(sorted_rows, sorted_rows$A)

#$`1`
#  A B
#1 1 2
#5 1 2

#$`2`
#  A B
#2 2 3
#6 2 3

#$`4`
#  A B
#4 4 6
#8 4 6

答案 2 :(得分:1)

我们可以split获得list data.frames

lst <- split(df, df$A)

如果我们需要分离/加入“A”的独特元素

 i1 <- sapply(lst, nrow)==1
 Others <-  do.call(rbind, lst[i1])

我们使用list2env在全局环境中创建单独的对象。

 list2env(setNames(lst[!i1], paste0("d", seq_along(lst[!i1]))), 
        envir= .GlobalEnv)

我们获得的输出是:

Others
#  A B
#3 3 4
#5 5 6
 d1
#  A B
#1 1 2
#5 1 2
 d2
#  A B
#2 2 3
#6 2 3
 d3
#  A B
#4 4 6
#8 4 6

更新

对于新数据集

lst <-  split(df, as.list(df), drop=TRUE)

i1 <- sapply(lst, nrow)==1
Others <-  do.call(rbind,setNames(lst[i1], NULL))

list2env(setNames(lst[!i1], paste0("d", seq_along(lst[!i1]))), 
     envir= .GlobalEnv)

d1
#  A B
#1 1 2
#5 1 2
d2
#  A B
#2 2 3
#6 2 3
d3
#  A B
#4 4 6
#8 4 6

Others
#  A B
#3 1 4
#7 5 6