【问题标题】:Filtering dataframe to only show 1 pair of two variables过滤数据框以仅显示一对两个变量
【发布时间】:2021-05-22 22:02:46
【问题描述】:

我有关于在不同时间点在不同医院工作的医生的信息。我想输出一个数据框,通知每家医院的每一对医生。我想在数据集中每对只查看一次;这意味着如果医生 A 和 B 在同一家医院一起工作,我希望看到 A-B 对或 B-A 对,但不能同时看到两者。

考虑一个非常简单的例子,医院 x-y-w,第 1-2 期和医生 A-B-C-D。

mydf <- data.frame(hospital = c("x","x","x","x","x","y","y","y","w","w","w","w"), 
                period = c(1,1,1,2,2,1,2,2,1,1,2,2), 
                physician = c("A","B","C","A","B","A","A","C","C","D","A","D"))

下面我设法得到所有对,但是每对显示两次(在fromto 之间交换)。怎样才能让每一对只在输出中出现一次?

pairs_df <- mydf %>%
  rename(from = physician) %>%
  left_join(mydf, by=c("hospital","period")) %>%
  rename(to = physician) %>%
  filter(from!=to)

【问题讨论】:

    标签: r filter dplyr


    【解决方案1】:

    我们可以使用pmin/pmaxduplicated 对'from'、'to' 列之间的元素进行逐行排序,在filter 中应用duplicated、否定(!) 以返回唯一行

    library(dplyr)
    pairs_df %>% 
         filter(!duplicated(cbind(pmax(from, to), pmin(from, to))))
    

    或使用base R

    subset(pairs_df, !duplicated(cbind(pmax(from, to), pmin(from, to))))
    

    -输出

         hospital period from to
    1         x      1    A  B
    2         x      1    A  C
    4         x      1    B  C
    11        w      1    C  D
    13        w      2    A  D
    

    注意:在这里,我们假设列是基于输入数据的character 类,即data.frame 构造默认使用stringsAsFactors = FALSE (&gt;= R 4.0.0),但之前默认为TRUE。如果列是factor,那么我们可以使用type.convert 转换为character

    pairs_df <- type.convert(pairs_df, as.is = TRUE)
    

    或在filter 之前将那些factor 转换为character

    pairs_df %>%
       mutate(across(where(is.factor), as.character)) %>%
       filter(!duplicated(cbind(pmax(from, to), pmin(from, to))))
    

    【讨论】:

    • 我不知道为什么,但是您的代码为我输出了不同的结果以及以下内容:Warning messages: 1: In Ops.factor(mmm, each) : ‘&lt;’ not meaningful for factors 2: In Ops.factor(mmm, each) : ‘&gt;’ not meaningful for factors
    • 输出行1, 3, 5, 12而不是1, 2, 4, 11, 13
    【解决方案2】:

    另一个选项是使用igraph

    get.data.frame(
      simplify(
        graph_from_data_frame(
          pairs_df[c("from", "to", "hospital", "period")],
          directed = FALSE
        ),
        edge.attr.comb = "first"
      )
    )
    

    给了

      from to hospital period
    1    A  B        x      1
    2    A  C        x      1
    3    A  D        w      2
    4    B  C        x      1
    5    C  D        w      1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-21
      • 2017-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-21
      • 1970-01-01
      相关资源
      最近更新 更多