基于每行不同列中的重复值的子集数据框

时间:2019-06-03 14:51:32

标签: r dataframe duplicates

我有一个密切相关的分离物的成对比较列表,列表中的一个元素看起来像这样:

df <- data.frame(Isolate1 = c("s1", "s2", "s2"), Ward1.x = c("1_1", "3_3", "3_3"), Ward1.y = c("NA", "2_1", "2_1"), Ward1.z = c("NA", "NA", "NA"),
           Isolate2 = c("s3", "s1", "s3"), Ward2.x = c("2_1", "1_1", "2_1"), Ward2.y = c("NA", "NA", "NA"), Ward2.z = c("NA", "NA", "NA"))

  Isolate1 Ward1.x Ward1.y Ward1.z Isolate2 Ward2.x Ward2.y Ward2.z
1       s1     1_1      NA      NA       s3     2_1      NA      NA
2       s2     3_3     2_1      NA       s1     1_1      NA      NA
3       s2     3_3     2_1      NA       s3     2_1      NA      NA

我现在想找出是否有成对比较,其中两个分离株都从同一个病房取样。因此,我想检查一下Ward1.x-Ward1.z和Ward2.x-Ward2.z列之间是否有重复项。

所以我的输出应该是仅包含df最后一行的数据帧,因为Ward1.y和Ward2.x相同,如下所示:

  Isolate1 Ward1.x Ward1.y Ward1.z Isolate2 Ward2.x Ward2.y Ward2.z
3       s2     3_3     2_1      NA       s3     2_1      NA      NA

我知道如何基于两列的相等性对数据框进行子集设置,但是如何检查多列之间的相等性?

1 个答案:

答案 0 :(得分:1)

使用apply的一种方法是过滤在"Ward1""Ward2"列中至少有一个非NA值的行。

col1 <- grep("^Ward1", names(df))
col2 <- grep("^Ward2", names(df))

df[apply(df, 1, function(x) any(na.omit(x[col1]) %in% na.omit(x[col2]))), ]

#  Isolate1 Ward1.x Ward1.y Ward1.z Isolate2 Ward2.x Ward2.y Ward2.z
#3       s2     3_3     2_1      NA       s3     2_1      NA      NA

使用与dplyrtidyr类似的逻辑,我们可以做到

library(dplyr)
library(tidyr)

df %>%
  mutate(row = row_number()) %>%
  gather(key, value, -starts_with("Iso"), -row) %>%
  group_by(row) %>%
  filter(any(na.omit(value[grep("Ward1", key)]) %in% 
             na.omit(value[grep("Ward2", key)]))) %>%
  spread(key, value)

# A tibble: 1 x 9
# Groups:   row [1]
#  Isolate1 Isolate2   row Ward1.x Ward1.y Ward1.z Ward2.x Ward2.y Ward2.z
#  <chr>    <chr>    <int> <chr>   <chr>   <chr>   <chr>   <chr>   <chr>  
#1 s2       s3           3 3_3     2_1     NA      2_1     NA      NA 

我们也可以使用intersect

df[apply(df, 1, function(x) length(na.omit(intersect(x[col1], x[col2])))) > 0, ]