【问题标题】:Spread multiple values to unique values in data frame in R [duplicate]将多个值传播到R中数据框中的唯一值[重复]
【发布时间】:2021-06-24 03:47:15
【问题描述】:

假设我有一个包含名称列表的数据框:

> x <- c("a", "b", "c")
> x <- as.data.frame(x)

#  > x
# 1 a
# 2 b
# 3 c

我想将每个唯一名称(x,下面)传播到每个名称(y,下面),并在原始列之前创建一个新列,以便新数据框如下所示:

#  > z
# x   y
# a   a
# a   b
# a   c
# b   a
# b   b
# b   c
# c   a
# c   b
# c   c 

这是为了在网络已满的 igraph 中创建一个“from”“to”边缘列表。

我怎么能这样做?我缺少一个简单的 tidyverse 解决方案吗?

【问题讨论】:

    标签: r dplyr tidyverse igraph


    【解决方案1】:

    您可以使用tidyr::expand_gridtidyr::crossing

    tidyr::expand_grid(a = x$x, b = x$x)
    #tidyr::crossing(a = x$x, b = x$x)
    
    #  a     b    
    #  <chr> <chr>
    #1 a     a    
    #2 a     b    
    #3 a     c    
    #4 b     a    
    #5 b     b    
    #6 b     c    
    #7 c     a    
    #8 c     b    
    #9 c     c    
    

    这类似于base R expand.grid,只是顺序不同。

    expand.grid(a = x$x, b = x$x)
    

    【讨论】:

    • 您好,亲爱的 Ronak Shah,我最近在 stackoverflow 上遇到了一个非常有趣的问题,但我找不到解决方案,因此没有得到解答。你介意我在评论中提到你吗,如果你知道我们如何解决这个问题,我将不胜感激。
    • 非常感谢。这是链接:stackoverflow.com/questions/66818393/…
    【解决方案2】:

    使用dplyrtidyr,您可以:

    x %>%
     mutate(y = x) %>%
     complete(y, x)
    
      y     x    
      <fct> <fct>
    1 a     a    
    2 a     b    
    3 a     c    
    4 b     a    
    5 b     b    
    6 b     c    
    7 c     a    
    8 c     b    
    9 c     c
    

    【讨论】:

    • 这是我找到的最简单的解决方案,谢谢!
    【解决方案3】:

    基础 R 解决方案:

    names <- c("a", "b", "c")
    
    x = rep(names, each=length(names))
    y = rep(names, length(names))
    df = data.frame(x,y)
    df
      x y
    1 a a
    2 a b
    3 a c
    4 b a
    5 b b
    6 b c
    7 c a
    8 c b
    9 c c
    

    【讨论】:

      【解决方案4】:

      您还可以使用expand 函数返回两列的所有可能组合:

      library(tidyr)
      
      x %>%
        mutate(y = x) %>%
        expand(x, y)
      
      # A tibble: 9 x 2
        x     y    
        <chr> <chr>
      1 a     a    
      2 a     b    
      3 a     c    
      4 b     a    
      5 b     b    
      6 b     c    
      7 c     a    
      8 c     b    
      9 c     c 
      
      

      你也可以使用crossing函数:

      x <- c("a", "b", "c")
      x <- as.data.frame(x)
      x$y <- c("a", "b", "c")
      
      crossing(x$x, x$y)        # But you can't just use it within a pipeline since the first argument is not data
      
      # A tibble: 9 x 2
        `x$x` `x$y`
        <chr> <chr>
      1 a     a    
      2 a     b    
      3 a     c    
      4 b     a    
      5 b     b    
      6 b     c    
      7 c     a    
      8 c     b    
      9 c     c 
      

      【讨论】:

        【解决方案5】:

        如果你真的想使用igraph,这里可能是一种选择

        make_full_graph(
          length(x),
          directed = TRUE,
          loops = TRUE
        ) %>%
          set_vertex_attr(name = "name", value = x) %>%
          get.data.frame()
        

        给了

          from to
        1    a  a
        2    a  b
        3    a  c
        4    b  a
        5    b  b
        6    b  c
        7    c  a
        8    c  b
        9    c  c
        

        【讨论】:

          猜你喜欢
          • 2021-11-10
          • 2016-12-23
          • 1970-01-01
          • 2020-03-17
          • 1970-01-01
          • 1970-01-01
          • 2017-01-05
          • 2018-07-26
          • 1970-01-01
          相关资源
          最近更新 更多