自动获取excel表格的列类型

Posted

技术标签:

【中文标题】自动获取excel表格的列类型【英文标题】:Get column types of excel sheet automatically 【发布时间】:2017-08-01 19:11:12 【问题描述】:

我有一个包含多张工作表的 excel 文件,每张都有几列,所以我不想单独指定列的类型,而是自动指定。我想像stringsAsFactors= FALSE 那样阅读它们,因为它正确地解释了列的类型。在我当前的方法中,列宽“0.492 ± 0.6”被解释为数字,返回 NA,“因为”stringsAsFactors 选项在read_excel 中不可用。所以在这里,我写了一个解决方法,它或多或少地工作得很好,但我不能在现实生活中使用,因为我不允许创建一个新文件。注意:我需要其他列作为数字或整数,也需要其他只有文本作为字符的列,就像 stringsAsFactors 在我的 read.csv 示例中所做的那样。

library(readxl)
file= "myfile.xlsx"
firstread<-read_excel(file, sheet = "mysheet", col_names = TRUE, na = "", skip = 0)
#firstread has the problem of the a column with "0.492 ± 0.6", 
#being interpreted as number (returns NA)
colna<-colnames(firstread)

# read every column as character
colnumt<-ncol(firstread)
textcol<-rep("text", colnumt)
secondreadchar<-read_excel(file, sheet = "mysheet", col_names = TRUE, 
col_types = textcol, na = "", skip = 0)
# another column, with the number 0.532, is now 0.5319999999999999 
# and several other similar cases.

# read again with stringsAsFactors 
# critical step, in real life, I "cannot" write a csv file.
write.csv(secondreadchar, "allcharac.txt", row.names = FALSE)
stringsasfactor<-read.csv("allcharac.txt", stringsAsFactors = FALSE)
colnames(stringsasfactor)<-colna
# column with "0.492 ± 0.6" now is character, as desired, others numeric as desired as well

【问题讨论】:

【参考方案1】:

这是一个脚本,用于导入您的 excel 文件中的所有数据。它将每张工作表的数据放在名为dfslist 中:

library(readxl)

# Get all the sheets
all_sheets <- excel_sheets("myfile.xlsx")

# Loop through the sheet names and get the data in each sheet
dfs <- lapply(all_sheets, function(x) 

  #Get the number of column in current sheet
  col_num <- NCOL(read_excel(path = "myfile.xlsx", sheet = x))

  # Get the dataframe with columns as text
  df <- read_excel(path = "myfile.xlsx", sheet = x, col_types = rep('text',col_num))

  # Convert to data.frame
  df <- as.data.frame(df, stringsAsFactors = FALSE)

  # Get numeric fields by trying to convert them into
  # numeric values. If it returns NA then not a numeric field.
  # Otherwise numeric.
  cond <- apply(df, 2, function(x) 
    x <- x[!is.na(x)]
    all(suppressWarnings(!is.na(as.numeric(x))))
  )
  numeric_cols <- names(df)[cond]
  df[,numeric_cols] <- sapply(df[,numeric_cols], as.numeric)

  # Return df in desired format
  df
)

# Just for convenience in order to remember
# which sheet is associated with which dataframe
names(dfs) <- all_sheets

流程如下:

首先,您使用excel_sheets 获取文件中的所有工作表,然后遍历工作表名称以创建数据框。对于这些数据帧中的每一个,您最初通过将col_types 参数设置为text 将数据导入为text。将数据框的列作为文本获取后,您可以将结构从 tibble 转换为 data.frame。之后,您会找到实际上是数值列的列,并将它们转换为数值。

编辑:

截至 4 月下旬,readxl 的新版本发布了,read_excel 函数获得了与此问题相关的两项增强功能。第一个是您可以使用提供给col_types 参数的参数“guess”让函数为您猜测列类型。第二个增强(第一个的推论)是将guess_max 参数添加到read_excel 函数中。这个新参数允许您设置用于猜测列类型的行数。本质上,我上面写的内容可以用以下方式缩短:

library(readxl)

# Get all the sheets
all_sheets <- excel_sheets("myfile.xlsx")

dfs <- lapply(all_sheets, function(sheetname) 
    suppressWarnings(read_excel(path = "myfile.xlsx", 
                                sheet = sheetname, 
                                col_types = 'guess', 
                                guess_max = Inf))
)

# Just for convenience in order to remember
# which sheet is associated with which dataframe
names(dfs) <- all_sheets

我建议您将readxl 更新到最新版本以缩短您的脚本,从而避免可能的烦恼。

我希望这会有所帮助。

【讨论】:

因为,as.data.frame 没有 na.strings,(我认为),我会包括,na.strings ***.com/questions/21422114/… @Ferroao,我不认为我听懂了你的意思。如果您碰巧认为答案需要编辑,请随时对其进行编辑并添加任何需要的内容。 @Ferraoo,请查看编辑。使用sapply 而不是apply

以上是关于自动获取excel表格的列类型的主要内容,如果未能解决你的问题,请参考以下文章

excel中,将一个工作表中几列数据自动更新到另一个工作表中对应的列中?

EXCEL表格中,通过商品名称自动获取对应的商品编码

接口自动化--操作Excel获取需要数据

Excel表格问题,怎样从一个表格中自动提取其中一部分表格

自动化冒烟测试,用Excel也能做

怎么样为Excel2010表格设置自动换行