【问题标题】:How do I select all unique combinations of two columns in an R data frame?如何选择 R 数据框中两列的所有唯一组合?
【发布时间】:2019-09-09 03:44:44
【问题描述】:

我有一个相关矩阵,我将其放入数据框中,如下所示:

row | var1 | var2 | cor
1   | A    | B    | 0.6
2   | B    | A    | 0.6
3   | A    | C    | 0.4
4   | C    | A    | 0.4

这些结果分别复制到 2 行中,同时包含“var1”和“var2”的组合。我只需要一个,最好先使用较低的变量(例如第 1 行和第 3 行)。

我已经用 dplyr 玩了两个小时并阅读了旧线程,但没有找到我需要的东西。

# get correlation of every concept versus every concept
data.cor <- data.jobs %>% 
  select(-y,-X) %>%
  as.matrix %>%
  cor %>%
  as.data.frame %>%
  rownames_to_column(var = 'var1') %>%
  gather(var2, value, -var1)

我希望输出看起来像这样:

row | var1 | var2 | cor
1   | A    | B    | 0.6
3   | A    | C    | 0.4

我试图在不使用循环的情况下做到这一点。

【问题讨论】:

标签: r dplyr tidyr


【解决方案1】:

这是tidyverse 的一种方式-

dat2 <- dat %>% 
  filter(!duplicated(paste0(pmax(var1, var2), pmin(var1, var2))))


# A tibble: 2 x 3
  var1  var2    cor
  <chr> <chr> <dbl>
1 A     B     0.600
2 A     C     0.400

数据 -

dat <- data_frame(
  var1 = LETTERS[c(1,2,1,3)],
  var2 = LETTERS[c(2,1,3,1)],
  cor = c(0.6,0.6,0.4,0.4))

注意:感谢@tmfmnk 清理了逻辑

【讨论】:

    【解决方案2】:

    dplyr 的可能性可能是:

    df %>%
     group_by(grp = paste0(pmin(var1, var2), pmax(var1, var2))) %>%
     slice(1) %>%
     ungroup() %>%
     select(-grp)
    
        row var1  var2    cor
      <int> <chr> <chr> <dbl>
    1     1 A     B       0.6
    2     3 A     C       0.4
    

    或者:

    df %>%
     group_by(grp = paste0(pmin(var1, var2), pmax(var1, var2))) %>%
     filter(row_number() == min(row_number())) %>%
     ungroup() %>%
     select(-grp)
    

    或者:

    df %>%
     group_by(grp = paste0(pmin(var1, var2), pmax(var1, var2))) %>%
     summarise_all(list(first)) %>%
     ungroup() %>%
     select(-grp)
    

    【讨论】:

      【解决方案3】:

      使用tidyverse 的解决方案。

      library(tidyverse)
      
      dat2 <- dat %>%
        mutate(Var = map2_chr(var1, var2, ~toString(sort(c(.x, .y))))) %>%
        distinct(Var, .keep_all = TRUE) %>%
        select(-Var)
      dat2
      #   row var1 var2 cor
      # 1   1    A    B 0.6
      # 2   3    A    C 0.4
      

      数据

      dat <- read.table(text = "row | var1 | var2 | cor
      1   | A    | B    | 0.6
      2   | B    | A    | 0.6
      3   | A    | C    | 0.4
      4   | C    | A    | 0.4",
                        sep = "|", stringsAsFactors = FALSE, header = TRUE, strip.white = TRUE)
      

      【讨论】:

        【解决方案4】:

        一种解决方案是对 var1 和 var2 进行排序(按字母顺序排列),然后使用唯一的。出于方便,我使用 data.table 进行了此操作,但可以使用 dplyr 来完成。

        library(data.table)
        
        dt = data.table(var1 = c("A", "B", "A", "C"), var2 = c("B", "A", "C", "A"), cor = c(0.6 ,0.6, 0.4, 0.4))
        
        dt[, var1_alt := min(var1, var2), by = 1:nrow(dt)]
        dt[, var2_alt := max(var1, var2), by = 1:nrow(dt)]
        
        dt = unique(dt[, .(var1 = var1_alt, var2 = var2_alt, cor)])
        

        【讨论】:

          【解决方案5】:

          这是另一个tidyverse 部分解决方案,因为我已经删除了行列:

          library(tidyverse)
          
          data.cor <-
            read.table(
              h = T,
              sep = "|",
              stringsAsFactors = F,
              text = "row | var1 | var2 | cor
                      1   | A    | B    | 0.6
                      2   | B    | A    | 0.6
                      3   | A    | C    | 0.4
                      4   | C    | A    | 0.4"
            ) %>%
            mutate_if(is.character, ~ trimws(.))
          
          data.cor
          #>   row var1 var2 cor
          #> 1   1    A    B 0.6
          #> 2   2    B    A 0.6
          #> 3   3    A    C 0.4
          #> 4   4    C    A 0.4
          
          df <- data.cor %>%
            gather(var, val, var1:var2) %>%
            distinct(cor, val) %>%
            group_by(cor) %>%
            mutate(x = paste("var", 1:n(), sep = "")) %>%
            spread(x, val) %>% 
            ungroup()
          
          df
          #> # A tibble: 2 x 3
          #>     cor var1  var2 
          #>   <dbl> <chr> <chr>
          #> 1   0.4 A     C    
          #> 2   0.6 A     B
          

          reprex package (v0.2.1) 于 2019 年 4 月 18 日创建

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-01-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多