【问题标题】:Elements of a dataframe as the column names of a new dataframe in R数据框的元素作为 R 中新数据框的列名
【发布时间】:2015-12-19 21:02:09
【问题描述】:

我在 r 中有以下名为 DF 的数据框:

   1          2         3    
1  VW       Mercedes  Audi                                    
2  Porsche  BMW       VW                                                    
3  Audi     Honda     Toyota                                             
4  Dodge    Opel      VW                                     
5  Lexus    Volvo     BMW                                                      
6  Dodge    VW        Porsche 

我想创建一个新的数据框(DF2),其中 DF 的每个元素都是新数据框的列名,DF 的列名是 DF2 的元素:

     Audi BMW Dodge Honda Lexus Mercedes Opel Porsche Toyota Volvo VW
1    3     0  0     0      0     2        0    0        0     0    1
2    0     2  0     0      0     0        0    1        0     0    3
3    1     0  0     2      0     0        0    0        3     0    0 
4    0     0  1     0      0     0        2    0        3     0    3     
5    0     3  0     0      1     0        0    0        0     2    0
6    0     0  1     0      0     0        0    3        0     0    2

【问题讨论】:

  • 如果你展示你为实现这一目标所做的尝试,你会在这里得到更好的回应。

标签: r data-science


【解决方案1】:

试试这个:

names <- unique(unlist(df))
x <- sapply(names, function(x) apply(df, 1, function(y) names(df)[x==y]))
x[] <- as.numeric(x)
x[is.na(x)] <- 0
x
     VW Porsche Audi Dodge Lexus Mercedes BMW Honda Opel Volvo Toyota
[1,] 1  0       3    0     0     2        0   0     0    0     0     
[2,] 3  1       0    0     0     0        2   0     0    0     0     
[3,] 0  0       1    0     0     0        0   2     0    0     3     
[4,] 3  0       0    1     0     0        0   0     2    0     0     
[5,] 0  0       0    0     1     0        3   0     0    2     0     
[6,] 2  3       0    1     0     0        0   0     0    0     0  

【讨论】:

    【解决方案2】:

    这是acast 来自reshape2 的另一个选项

    library(reshape2)
    acast(melt(as.matrix(df)), Var1~value, value.var='Var2', fill=0)
    #  Audi BMW Dodge Honda Lexus Mercedes Opel Porsche Toyota Volvo VW
    #1    3   0     0     0     0        2    0       0      0     0  1
    #2    0   2     0     0     0        0    0       1      0     0  3
    #3    1   0     0     2     0        0    0       0      3     0  0
    #4    0   0     1     0     0        0    2       0      0     0  3
    #5    0   3     0     0     1        0    0       0      0     2  0
    #6    0   0     1     0     0        0    0       3      0     0  2
    

    【讨论】:

      【解决方案3】:

      另一种选择:

      library(tidyr)
      library(dplyr)
      
      DF %>%
        add_rownames() %>%
        gather(key, value, -rowname, convert = TRUE) %>% 
        spread(value, key, fill = 0) %>%
        select(-rowname)
      

      这给出了:

      #Source: local data frame [6 x 11]
      #
      #   Audi   BMW Dodge Honda Lexus Mercedes  Opel Porsche Toyota Volvo    VW
      #  (dbl) (dbl) (dbl) (dbl) (dbl)    (dbl) (dbl)   (dbl)  (dbl) (dbl) (dbl)
      #1     3     0     0     0     0        2     0       0      0     0     1
      #2     0     2     0     0     0        0     0       1      0     0     3
      #3     1     0     0     2     0        0     0       0      3     0     0
      #4     0     0     1     0     0        0     2       0      0     0     3
      #5     0     3     0     0     1        0     0       0      0     2     0
      #6     0     0     1     0     0        0     0       3      0     0     2
      

      【讨论】:

      • 非常感谢,tidyr 和 dplyr 逻辑对我来说有点难以理解,我从哪里可以了解这个管道到数据帧的作用是什么?
      • 看看cran.r-project.org/web/packages/magrittr/vignettes/… - 尝试执行每个步骤,看看发生了什么。您可以在函数前使用? 或将其包装在help() 中以获取有关其工作原理的详细信息。
      【解决方案4】:

      这也有效:

      DF <- read.table( text =
      "  VW       Mercedes  Audi                                    
         Porsche  BMW       VW                                                    
         Audi     Honda     Toyota                                             
         Dodge    Opel      VW                                     
         Lexus    Volvo     BMW                                                      
         Dodge    VW        Porsche " )
      
      DF1 <- apply(DF,1:2,as.character) # Convert factors to strings, if necessary.
      cars <- sort(unique(c(as.matrix(DF1))))
      DF2 <- data.frame( matrix(0,nrow(DF),length(cars)) )
      colnames(DF2) <- cars
      for ( i in 1:nrow(DF) ) { DF2[i,DF1[i,]] <- 1:ncol(DF) }
      

      for-loop 是无害的,因为它没有在其中生长。

        Audi BMW Dodge Honda Lexus Mercedes Opel Porsche Toyota Volvo VW
      1    3   0     0     0     0        2    0       0      0     0  1
      2    0   2     0     0     0        0    0       1      0     0  3
      3    1   0     0     2     0        0    0       0      3     0  0
      4    0   0     1     0     0        0    2       0      0     0  3
      5    0   3     0     0     1        0    0       0      0     2  0
      6    0   0     1     0     0        0    0       3      0     0  2
      > 
      

      for-loop 更快。很奇怪,不是吗?

      library(microbenchmark)
      
      mra68 <- function()
      {
        DF1 <- apply(DF,1:2,as.character)
        cars <- sort(unique(c(as.matrix(DF1))))
          DF2 <- data.frame( matrix(0,nrow(DF),length(cars)) )
        colnames(DF2) <- cars
          for ( i in 1:nrow(DF) ) { DF2[i,DF1[i,]] <- 1:ncol(DF) }
          return( DF2 )
      }
      
      DatamineR <- function()
      {
        names <- unique(unlist(DF))
        x <- sapply(names, function(x) apply(DF, 1, function(y) names(DF)[x==y]))
        x[] <- as.numeric(x)
        x[is.na(x)] <- 0
        return(x)
      }
      
      microbenchmark( mra68(), DatamineR() )
      

      .

      > microbenchmark( mra68(), DatamineR() )
      Unit: milliseconds
              expr      min        lq     mean    median        uq       max neval
           mra68() 2.360912  4.618337  4.74136  4.738126  4.931509  8.496653   100
       DatamineR() 8.151552 16.083225 16.42256 16.284309 16.480636 20.860074   100
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-16
        • 1970-01-01
        • 2018-03-05
        • 2014-12-12
        • 1970-01-01
        相关资源
        最近更新 更多