【问题标题】:Use dplyr in order to create a consensus column使用 dplyr 创建共识列
【发布时间】:2019-05-15 20:54:44
【问题描述】:

我有一个数据框:

  Groups    Name    Category    value
        G1  A   cat1    20
        G1  A   cat2    1
        G1  B   cat3    21
        G1  B   cat3    23
        G2  B   cat4    32
        G2  C   cat2    23
        G2  C   cat2    21

我想添加一个新列consensus_category,例如:

Groups  Name    Category    value   consensus_category
G1  A   cat1    20  cat2
G1  A   cat2    1   cat2
G1  B   cat3    21  cat2
G1  B   cat3    23  cat2
G2  A   cat4    32  cat4
G2  C   cat2    23  cat4
G2  C   cat2    21  cat4

这个想法是我有一个 vector = c("A") 对应于数据框中的特定名称

从这个名字,我想为同一Groups中的所有其他行写对应的Category,但如果在两个Categories之间有一个ex-aequo,那么获胜者就是@987654329 @ 最低的Value。 (如:

G1  A   cat1    20  cat2
G1  A   cat2    1   cat2

cat2 获胜,因为1 < 20

我试过了:

df %>%
  group_by(Groups) %>%
  add_count(Category) %>%
  top_n(1, n) %>%
  top_n(-1, Value) %>%
  distinct(consensus_category = Category) %>%
  right_join(df) 

但我不知道如何指定我想要作为共识指南向量(A) 中的值。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    使用dplyr可以找到组内有vecName,得到最小的value并从中提取出对应的Category。这是假设每个Groups 都至少有一个vec 的值。

    library(dplyr)
    
    vec <- "A"
    
    df %>%
      group_by(Groups) %>%
      mutate(consensus_category = Category[value == min(value[Name == vec])])
    
    #  Groups Name  Category value consensus_category
    #  <fct>  <fct> <fct>    <int> <fct>             
    #1 G1     A     cat1        20 cat2              
    #2 G1     A     cat2         1 cat2              
    #3 G1     B     cat3        21 cat2              
    #4 G1     B     cat3        23 cat2              
    #5 G2     A     cat4        32 cat4              
    #6 G2     C     cat2        23 cat4              
    #7 G2     C     cat2        21 cat4      
    

    如果vec 中有多个值,您可能需要Name %in% vec 而不是==

    数据

    df <- structure(list(Groups = c("G1", "G1", "G1", "G1", "G2", "G2", 
    "G2"), Name = c("A", "A", "B", "B", "A", "C", "C"), Category = 
    c("cat1", "cat2", "cat3", "cat3", "cat4", "cat2", "cat2"), value = 
    c(20L, 1L, 21L, 23L, 32L, 23L, 21L)), class = "data.frame", row.names = 
    c(NA, -7L))
    

    【讨论】:

      【解决方案2】:

      data.table 的选项

      library(data.table)
      setDT(df)[, consensus_category := Category[value ==
            min(value[Name == vec])],  Groups]
      df
      #   Groups Name Category value consensus_category
      #1:     G1    A     cat1    20               cat2
      #2:     G1    A     cat2     1               cat2
      #3:     G1    B     cat3    21               cat2
      #4:     G1    B     cat3    23               cat2
      #5:     G2    A     cat4    32               cat4
      #6:     G2    C     cat2    23               cat4
      #7:     G2    C     cat2    21               cat4
      

      数据

      df <- structure(list(Groups = c("G1", "G1", "G1", "G1", "G2", "G2", 
      "G2"), Name = c("A", "A", "B", "B", "A", "C", "C"), Category = 
      c("cat1", "cat2", "cat3", "cat3", "cat4", "cat2", "cat2"), value = 
      c(20L, 1L, 21L, 23L, 32L, 23L, 21L)), class = "data.frame", row.names = 
      c(NA, -7L))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-10-14
        • 1970-01-01
        • 1970-01-01
        • 2021-10-16
        • 1970-01-01
        • 2019-11-28
        • 1970-01-01
        相关资源
        最近更新 更多