【问题标题】:Subset dataframe based on duplicate values in different columns per row基于每行不同列中的重复值的子集数据框
【发布时间】:2019-06-03 14:51:32
【问题描述】:

我有一个密切相关的分离株的成对比较列表,列表中的一个元素如下所示:

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

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

【问题讨论】:

  • 你能显示预期的输出吗
  • @akrun 我更新了问题,希望它现在更清楚我需要什么

标签: r dataframe duplicates


【解决方案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, ]  

【讨论】:

    猜你喜欢
    • 2018-04-28
    • 2020-02-08
    • 1970-01-01
    • 2017-04-06
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    相关资源
    最近更新 更多