简体   繁体   English

查找一列中相同但另一列中相同的行

[英]Find rows that are identical in one column but not another

There should be a fairly simple solution to this but it's giving me trouble.应该有一个相当简单的解决方案,但这给我带来了麻烦。 I have a DF similar to this:我有一个与此类似的 DF:

> df <- data.frame(name = c("george", "george", "george", "sara", "sara", "sam", "bill", "bill"),
                  id_num = c(1, 1, 2, 3, 3, 4, 5, 5))
> df
    name id_num
1 george      1
2 george      1
3 george      2
4   sara      3
5   sara      3
6    sam      4
7   bill      5
8   bill      5

I'm looking for a way to find rows where the name and ID numbers are inconsistent in a very large dataset.我正在寻找一种方法来查找在非常大的数据集中名称和 ID 号不一致的行。 Ie, George should always be "1" but in row three there is a mistake and he has also been assigned ID number "2".即,乔治应该始终是“1”,但在第三行有一个错误,他也被分配了 ID 号“2”。

I think the easiest way will be to use dplyr::count twice, hence for your example:我认为最简单的方法是使用dplyr::count两次,因此对于您的示例:

df %>% 
   count(name, id) %>% 
   count(name) 

The first count will give:第一个计数将给出:

name   id   n
george  1   2
george  2   1
sara    3   2
sam     4   1
bill    5   2

Then the second count will give:然后第二个计数将给出:

name    n
george  2
sara    1 
sam     1 
bill    1

Of course, you could add filter(n > 1) to the end of your pipe, too, or arrange(desc(n))当然,您也可以将filter(n > 1)添加到 pipe 的末尾,或者arrange(desc(n))

df %>% 
   count(name, id) %>% 
   count(name) %>% 
   arrange(desc(n)) %>% 
   filter(n > 1) 

Using tapply() to calculate number of ID's per name, then subset for greater than 1.使用tapply()计算每个名称的 ID 数,然后是大于 1 的子集。

res <- with(df, tapply(id_num, list(name), \(x) length(unique(x))))
res[res > 1]
# george 
#      2 

You probably want to correct this.您可能想要更正此问题。 A safe way is to rebuild the numeric ID's using as.factor() ,一种安全的方法是使用as.factor()重建数字 ID,

df$id_new <- as.integer(as.factor(df$name))
df
#     name id_num id_new
# 1 george      1      2
# 2 george      1      2
# 3 george      2      2
# 4   sara      3      4
# 5   sara      3      4
# 6    sam      4      3
# 7   bill      5      1
# 8   bill      5      1

where numbers are assigned according to the names in alphabetical order, or factor() , reading in the levels in order of appearance.其中数字是根据按字母顺序或factor()的名称分配的,按出现顺序读取级别。

df$id_new2 <- as.integer(factor(df$name, levels=unique(df$name)))
df
#     name id_num id_new id_new2
# 1 george      1      2       1
# 2 george      1      2       1
# 3 george      2      2       1
# 4   sara      3      4       2
# 5   sara      3      4       2
# 6    sam      4      3       3
# 7   bill      5      1       4
# 8   bill      5      1       4

Note: R >= 4.1 used.注意:使用 R >= 4.1。


Data:数据:

df <- structure(list(name = c("george", "george", "george", "sara", 
"sara", "sam", "bill", "bill"), id_num = c(1, 1, 2, 3, 3, 4, 
5, 5)), class = "data.frame", row.names = c(NA, -8L))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM