【问题标题】:Difference between as.data.frame(x) and data.frame(x)as.data.frame(x) 和 data.frame(x) 的区别
【发布时间】:2014-02-05 10:13:09
【问题描述】:

as.data.frame(x) 和 data.frame(x) 有什么区别

在以下示例中,除了列名之外,结果是相同的。

x <- matrix(data=rep(1,9),nrow=3,ncol=3)
> x
     [,1] [,2] [,3]
[1,]    1    1    1
[2,]    1    1    1
[3,]    1    1    1
> data.frame(x)
  X1 X2 X3
1  1  1  1
2  1  1  1
3  1  1  1
> as.data.frame(x)
  V1 V2 V3
1  1  1  1
2  1  1  1
3  1  1  1

【问题讨论】:

标签: r dataframe


【解决方案1】:

正如 Jaap 所说,data.frame() 调用 as.data.frame() 但这是有原因的:

as.data.frame() 是一种强制其他对象到类data.frame 的方法。如果您正在编写自己的包,您可以将转换your_class 对象的方法存储在as.data.frame.your_class() 下。这里只是几个例子。

methods(as.data.frame)
 [1] as.data.frame.AsIs            as.data.frame.Date           
 [3] as.data.frame.POSIXct         as.data.frame.POSIXlt        
 [5] as.data.frame.aovproj*        as.data.frame.array          
 [7] as.data.frame.character       as.data.frame.complex        
 [9] as.data.frame.data.frame      as.data.frame.default        
[11] as.data.frame.difftime        as.data.frame.factor         
[13] as.data.frame.ftable*         as.data.frame.integer        
[15] as.data.frame.list            as.data.frame.logLik*        
[17] as.data.frame.logical         as.data.frame.matrix         
[19] as.data.frame.model.matrix    as.data.frame.numeric        
[21] as.data.frame.numeric_version as.data.frame.ordered        
[23] as.data.frame.raw             as.data.frame.table          
[25] as.data.frame.ts              as.data.frame.vector         

   Non-visible functions are asterisked

【讨论】:

    【解决方案2】:

    data.frame() 可用于构建数据框,而as.data.frame() 只能用于将其他对象强制转换为数据框。

    例如:

    # data.frame()
    df1 <- data.frame(matrix(1:12,3,4),1:3)
    
    # as.data.frame()
    df2 <- as.data.frame(matrix(1:12,3,4),1:3)
    
    df1
    #   X1 X2 X3 X4 X1.3
    # 1  1  4  7 10    1
    # 2  2  5  8 11    2
    # 3  3  6  9 12    3
    
    df2
    #   V1 V2 V3 V4
    # 1  1  4  7 10
    # 2  2  5  8 11
    # 3  3  6  9 12
    

    【讨论】:

    • 不一定。试试is.object(1:5); as.data.frame(1:5)
    【解决方案3】:

    正如您所说,结果确实略有不同,这意味着它们并不完全相等:

    identical(data.frame(x),as.data.frame(x))
    [1] FALSE
    

    因此,您可能需要注意在使用哪一个时保持一致。

    但同样值得注意的是as.data.frame更快:

    library(microbenchmark)
    microbenchmark(data.frame(x),as.data.frame(x))
    Unit: microseconds
                 expr    min     lq median      uq     max neval
        data.frame(x) 71.446 73.616  74.80 78.9445 146.442   100
     as.data.frame(x) 25.657 27.631  28.42 29.2100  93.155   100
    
    y <- matrix(1:1e6,1000,1000)
    microbenchmark(data.frame(y),as.data.frame(y))
    Unit: milliseconds
                 expr      min       lq   median       uq       max neval
        data.frame(y) 17.23943 19.63163 23.60193 41.07898 130.66005   100
     as.data.frame(y) 10.83469 12.56357 14.04929 34.68608  38.37435   100
    

    【讨论】:

    • 不同的是,列名的创建方式可以不同...还有什么?
    【解决方案4】:

    当您查看他们的主要论点时,差异会变得更加明显:

    • as.data.frame(x, ...):如果对象是数据框,check,如果可能,coerce。这里,“x”可以是任何 R 对象。
    • data.frame(...):构建一个数据框。在这里,“...”允许指定所有组件(即数据框的变量)。

    因此,Ophelia 的结果是相似的,因为两个函数都接收一个矩阵作为参数:但是,当这些函数接收 2 个(或更多)向量时,区别变得更加清晰:

    > # Set seed for reproducibility
    > set.seed(3)
    
    > # Create one int vector
    > IDs <- seq(1:10)
    > IDs
     [1]  1  2  3  4  5  6  7  8  9 10
    > # Create one char vector
    > types <- sample(c("A", "B"), 10, replace = TRUE)
    > types
     [1] "A" "B" "A" "A" "B" "B" "A" "A" "B" "B"
    
    > # Try to use "as.data.frame" to coerce components into a dataframe
    > dataframe_1 <- as.data.frame(IDs, types)
    > # Look at the result
    > dataframe_1
    Error in (function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE,  : 
      duplicate row.names: A, B
    > # Inspect result with head
    > head(dataframe_1, n = 10)
        IDs
    A     1
    B     2
    A.1   3
    A.2   4
    B.1   5
    B.2   6
    A.3   7
    A.4   8
    B.3   9
    B.4  10
    > # Check the structure
    > str(dataframe_1)
    'data.frame':   10 obs. of  1 variable:
     $ IDs: int  1 2 3 4 5 6 7 8 9 10
    
    > # Use instead "data.frame" to build a data frame starting from two components
    > dataframe_2 <- data.frame(IDs, types) 
    > # Look at the result
    > dataframe_2
       IDs types
    1    1     A
    2    2     B
    3    3     A
    4    4     A
    5    5     B
    6    6     B
    7    7     A
    8    8     A
    9    9     B
    10  10     B
    > # Inspect result with head
    > head(dataframe_2, n = 10)
       IDs types
    1    1     A
    2    2     B
    3    3     A
    4    4     A
    5    5     B
    6    6     B
    7    7     A
    8    8     A
    9    9     B
    10  10     B
    > # Check the structure
    > str(dataframe_2)
    'data.frame':   10 obs. of  2 variables:
     $ IDs  : int  1 2 3 4 5 6 7 8 9 10
     $ types: Factor w/ 2 levels "A","B": 1 2 1 1 2 2 1 1 2 2
    

    如您所见,“data.frame()”工作正常,而“as.data.frame()”会产生错误,因为它将第一个参数识别为要检查和强制的对象。

    总而言之,“as.data.frame()”应该用于将单个 R 对象转换/强制为数据框(正如您正确使用矩阵所做的那样),而“data.frame()”用于从头开始构建数据框。

    【讨论】:

      【解决方案5】:

      试试

      colnames(x) <- c("C1","C2","C3")
      

      然后两者都会给出相同的结果

      identical(data.frame(x), as.data.frame(x))
      

      更令人吃惊的是以下内容:

      list(x)
      

      提供一个单元素列表,元素是矩阵 x;而

      as.list(x)
      

      给出一个包含 9 个元素的列表,每个矩阵条目一个

      MM

      【讨论】:

        【解决方案6】:

        查看代码,as.data.frame 失败得更快。 data.frame 将发出警告,并在存在重复时执行诸如删除行名之类的操作:

        > x <- matrix(data=rep(1,9),nrow=3,ncol=3)
        > rownames(x) <- c("a", "b", "b")
        > data.frame(x)
          X1 X2 X3
        1  1  1  1
        2  1  1  1
        3  1  1  1
        Warning message:
        In data.row.names(row.names, rowsi, i) :
          some row.names duplicated: 3 --> row.names NOT used
        
        > as.data.frame(x)
        Error in (function (..., row.names = NULL, check.rows = FALSE, check.names =        
        TRUE,  : 
          duplicate row.names: b
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-07-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-08-05
          • 2018-03-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多