在R中仅删除数据帧中的相邻重复项

时间:2014-11-19 16:34:15

标签: r duplicates

我在R中有一个数据框, 应该有重复项。但是,我需要删除一些重复项。特别是,我只想删除与行相邻的重复项,但保留其余部分。例如,假设我有数据框:

df = data.frame(x = c("A", "B", "C", "A", "B", "C", "A", "B", "B", "C"), 
                y = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))

这导致以下数据框

x   y
A   1
B   2
C   3
A   4
B   5
C   6
A   7
B   8
B   9
C   10

在这种情况下,我希望重复" A,B,C,A,B,C等等#34;。但是,如果我看到相邻行重复,则只会出现问题。在我上面的例子中,那将是第8行和第9行,副本是" B"彼此相邻。

在我的数据集中,每当发生这种情况时,第一个实例始终是用户错误,第二个实例始终是正确的版本。在极少数情况下,可能存在重复发生3次(或更多次)的实例。但是,在每种情况下,我总是希望保持最后一次出现。因此,按照上面的例子,我希望最终的数据集看起来像

A   1
B   2
C   3
A   4
B   5
C   6
A   7
B   9
C   10

在R中有一种简单的方法吗?提前感谢您的帮助!


编辑:2014年11月19日美国东部时间下午12:14 用户Akron(拼写?)发布的解决方案已被删除。我现在明白为什么,因为它似乎对我有用?

解决方案是

df = df[with(df, c(x[-1]!= x[-nrow(df)], TRUE)),]

它似乎对我有用,为什么会被删除?例如,在连续重复次数超过2的情况下:

df = data.frame(x = c("A", "B", "B", "B", "C", "C", "C", "A", "B", "C", "A", "B", "B", "C"), y = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14))
   x  y
1  A  1
2  B  2
3  B  3
4  B  4
5  C  5
6  C  6
7  C  7
8  A  8
9  B  9
10 C 10
11 A 11
12 B 12
13 B 13
14 C 14

> df = df[with(df, c(x[-1]!= x[-nrow(df)], TRUE)),]
> df
   x  y
1  A  1
4  B  4
7  C  7
8  A  8
9  B  9
10 C 10
11 A 11
13 B 13
14 C 14

这似乎有用吗?

3 个答案:

答案 0 :(得分:4)

尝试

 df[with(df, c(x[-1]!= x[-nrow(df)], TRUE)),]
#   x  y
#1  A  1
#2  B  2
#3  C  3
#4  A  4
#5  B  5
#6  C  6
#7  A  7
#9  B  9
#10 C 10

解释

这里,我们将元素与前面的元素进行比较。这可以通过从列中删除first element并将该列与从中移除last element的列进行比较(以使长度变得相等)来完成。

 df$x[-1] #first element removed
 #[1] B C A B C A B B C
 df$x[-nrow(df)]
  #[1] A B C A B C A B B #last element `C` removed

 df$x[-1]!=df$x[-nrow(df)]
 #[1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE

在上面,我们删除了一个元素时,1的长度比nrowdf。为了弥补这一点,我们可以连接TRUE,然后使用此index对数据集进行子集化。

答案 1 :(得分:4)

这是一个rle解决方案:

df[cumsum(rle(as.character(df$x))$lengths), ]
#    x  y
# 1  A  1
# 2  B  2
# 3  C  3
# 4  A  4
# 5  B  5
# 6  C  6
# 7  A  7
# 9  B  9
# 10 C 10

说明:

RLE代表运行长度编码。它生成一个向量列表。一个是运行,值和其他长度是每个值的连续重复次数。例如,x <- c(3, 2, 2, 3)的运行向量为c(3, 2, 3),长度为c(1, 2, 1)。在此示例中,长度的累积总和产生c(1, 3, 4)。使用此向量的子集x,您将获得c(3, 2, 3)。请注意,长度向量的第二个元素是向量的第三个元素,在该特定的“运行”中最后一个出现2。

答案 2 :(得分:2)

您也可以尝试

df[c(diff(as.numeric(df$x)), 1) != 0, ]

如果x属于character级别(而不是factor),请尝试

df[c(diff(as.numeric(factor(df$x))), 1) != 0, ]
#    x  y
# 1  A  1
# 2  B  2
# 3  C  3
# 4  A  4
# 5  B  5
# 6  C  6
# 7  A  7
# 9  B  9
# 10 C 10