【问题标题】:Reading horizontal (row-based) data from xlsx files into R data frames将 xlsx 文件中的水平(基于行)数据读入 R 数据帧
【发布时间】:2016-02-05 21:41:27
【问题描述】:

这是与this one相关的“让我们尝试另一种方式”的帖子:

是否可以定义/修改一个阅读功能,

  • 可以处理存储在xlsx 文件中的数据基于行(即每一行代表一个变量)的事实

  • 并相应地对其进行转换,以便可以将其存储在 基于列的 data.frame 中(即,过去 xlsx 中的 变为一个

  • 同时捕获基于行的变量的基础类/数据类型

关于csv 文件,我可能会先转向readLines,但不幸的是xlsx 对我来说仍然是一个黑匣子。

这是一个小 xlsx 文件,其中包含两种数据方向的示例:https://github.com/rappster/stackoverflow/blob/master/excel/row-and-column-based-data.xlsx

【问题讨论】:

    标签: r excel dataframe xlsx transpose


    【解决方案1】:

    稍微修改xlsx包中的read.xlsx函数怎么样:

    library(xlsx)
    read.transposed.xlsx <- function(file,sheetIndex) {
            df <- read.xlsx(file, sheetIndex = sheetIndex , header = FALSE)
            dft <- as.data.frame(t(df[-1]), stringsAsFactors = FALSE) 
            names(dft) <- df[,1] 
            dft <- as.data.frame(lapply(dft,type.convert))
            return(dft)            
    }
    
    # Let's test it
    read.transposed.xlsx("row-and-column-based-data.xlsx", sheetIndex = 2)
    #    variable var_1 var_2 var_3
    #1 2016-01-01     1     a  TRUE
    #2 2016-01-02     2     b FALSE
    #3 2016-01-03     3     c  TRUE
    

    【讨论】:

    • 感谢您抽出宝贵时间。问题是当变量是基于行而不是基于列时读取/捕获变量的基础类信息:var_1 最终应该是numericvar_2 可以保持charactervar_3 需要最后是logical。这正是棘手的部分。
    • 答案已更新,我们可以使用utils 中的type.convert 将字符列转换为适当的类。
    • 你太棒了! type.convert 正是丢失的拼图!以前没听说过,非常感谢!!
    • 你可以通过dft &lt;- as.data.frame(t(df[-1]), stringsAsFactors = FALSE)然后dft &lt;- as.list(dft)而不是调用lapply()来简化一些事情
    • 如果这种方法导致错误,我使用了另一种解决方案 - 请参阅我的答案here
    【解决方案2】:
       > library(openxlsx)
    > library(reshape)
    > x=read.xlsx("row-and-column-based-data.xlsx",sheet = 2);
    > x
      variable 2016-01-01 2016-01-02 2016-01-03
    1    var_1          1          2          3
    2    var_2          a          b          c
    3    var_3       TRUE      FALSE       TRUE
    > y=t(x)
    > colnames(y)=y[1,]
    > y=y[2:nrow(y),]
    > cc=data.frame(y, stringsAsFactors = F)
    > cc
               var_1 var_2 var_3
    2016-01-01     1     a  TRUE
    2016-01-02     2     b FALSE
    2016-01-03     3     c  TRUE
    > sapply(cc, class)
          var_1       var_2       var_3 
    "character" "character" "character" 
    > write.csv(cc,"temp.csv")
    > bb=read.csv("temp.csv")  #infer magically types
    > bb
               X var_1 var_2 var_3
    1 2016-01-01     1     a  TRUE
    2 2016-01-02     2     b FALSE
    3 2016-01-03     3     c  TRUE
    > sapply(bb, class)
            X     var_1     var_2     var_3 
     "factor" "integer"  "factor" "logical" 
    

    如果您更喜欢字符数据类型,请使用 stringsAsFactors=F:

    > bb=read.csv("temp.csv", stringsAsFactors = F)  #infer magically types
    > bb
               X var_1 var_2 var_3
    1 2016-01-01     1     a  TRUE
    2 2016-01-02     2     b FALSE
    3 2016-01-03     3     c  TRUE
    > sapply(bb, class)
              X       var_1       var_2       var_3 
    "character"   "integer" "character"   "logical" 
    

    【讨论】:

    • 对不起,我忘了强调需要捕获底层类/数据类型信息的一点:值"TRUE""FALSE"应该是logicals,数值应该是@ 987654326@s.
    • 我还认为您有旧版本的示例文件,抱歉!我大约在 20 分钟前更新了它。
    • 非常感谢您的努力!我认为我们找到了一个基于 type.convert 的好方法 - 真的是一个简洁的小辅助函数!
    【解决方案3】:

    你也可以用这个代码试试这个utility

    install.packages("remotes")
    remotes::install_github("atusy/mytools")
    library(mytools)
    my_df <- read_excel2("my_excel_file.xlsx", sheet = 1, transposing = TRUE, error_as_NA = TRUE, rm_blank_col = TRUE)
    
    

    我的 excel 表在第二列中有所需的 column 标题,这意味着它们最终在第一行,然后我用 janitor 修复了该方法描述here

    x %>%
      row_to_names(row_number = 1)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-02
      • 2021-09-04
      • 2015-02-26
      • 1970-01-01
      • 2022-01-07
      • 2013-06-24
      相关资源
      最近更新 更多