20

xlsx2007 のテーブルを下のR 3.2.1patchedパッケージを使用してインポートしています。テーブルのサイズは、25,000 行 x 200 列のオーダーです。readxl 0.1.0Windows 7 64

機能read_excel()は扱います。私の唯一の問題は、列クラス (データ型) をまばらに入力された列に割り当てることです。たとえば、特定の列が 20,000 行に対して NA である場合、行 20,001 で文字値を取ります。read_excel()列の最初の n 行をスキャンして検索する場合のみ、列の型が数値にデフォルト設定されているように見えますNAs。問題の原因となっているデータは、数値が割り当てられた列の文字です。エラー制限に達すると、実行が停止します。実際にはスパース列のデータが必要なので、エラー制限を高く設定しても解決策にはなりません。

スローされた警告を確認することで、問題のある列を特定できます。パッケージのドキュメントに従って引数を設定することにより、read_excel()列のデータ型をアサートするオプションがあります。col_types

スプレッドシートから推測するか、 、、またはNULLを含む文字ベクトルから推測します。blanknumericdatetext

しかし、これは長さ 200 のベクトルを構成し、問題のある列に対応するいくつかの位置blankとほぼすべての位置に配置する必要があるということでしょうか?text

おそらく、数行のRコードでこれを行う方法があります。必要な長さのベクトルを作成し、blanks で埋めます。おそらく、強制される列の数を含む別のベクトル、そして...または、その推測が期待どおりではない列だけtextを呼び出すことができるかもしれません。read_excel()

提案をいただければ幸いです。

前もって感謝します。

4

6 に答える 6

12

readxlバージョン 1.x以降の新しいソリューション:

現在推奨されている回答のソリューションはreadxl、使用されているパッケージ内部関数readxl:::xlsx_col_typesが存在しなくなったため、 0.1.0 より新しいバージョンでは機能しなくなりました。

新しい解決策は、新しく導入されたパラメーターguess_maxを使用して、列の適切なデータ型を「推測」するために使用される行数を増やすことです。

read_excel("My_Excel_file.xlsx", sheet = 1, guess_max = 1048576)

値 1,048,576 は現在 Excel でサポートされている最大行数です。Excel の仕様を参照してください: https://support.office.com/en-us/article/Excel-specifications-and-limits-1672b34d-7043-467e-8e27 -269d656771c3

PS:すべての行を使用してデータ型を推測するパフォーマンスが気になる場合:read_excelファイルを 1 回だけ読み取るようで、推測はメモリ内で行われるため、保存された作業に比べてパフォーマンスのペナルティは非常に小さくなります。

于 2017-09-08T17:58:04.240 に答える
6

同様の問題が発生しました。

私の場合、空の行と列がセパレータとして使用されました。そして、シートには(さまざまな形式の)多くの表が含まれていました。したがって、{openxlsx}パッケージ{readxl}はこの状況に適していないため、openxlsx が空の列を削除します (この動作を変更するパラメーターはありません)。Readxl パッケージは説明どおりに動作し、一部のデータが失われる可能性があります。

結果として、大量の Excel データを自動的に処理したい場合の最善の解決策は、「テキスト」形式を変更せずにシートを読み取り、ルールに従って data.frames を処理することだと思います。

この関数は変更なしでシートを読み取ることができます (@jack-wasey に感謝):

loadExcelSheet<-function(excel.file, sheet)
{
  require("readxl")
  sheets <- readxl::excel_sheets(excel.file)
  sheet.num <- match(sheet, sheets) - 1
  num.columns <- length(readxl:::xlsx_col_types(excel.file, sheet =   sheet.num,
                                              nskip = 0, n = 1))

  return.sheet <- readxl::read_excel(excel.file, sheet = sheet,
                                col_types = rep("text", num.columns),
                                col_names = F)
  return.sheet 
}
于 2015-12-01T08:05:31.290 に答える
6

それは、データが異なる列の異なる場所でまばらであるかどうか、およびそれがどの程度まばらであるかによって異なります。行を増やしても解析が改善されないことがわかりました.大部分はまだ空白であり、後で日付になったとしてもテキストとして解釈されます..

1 つの回避策は、Excel テーブルの最初のデータ行を生成してすべての列の代表的なデータを含め、それを使用して列の種類を推測することです。元のデータをそのまま残したいので、これは好きではありません。

別の回避策として、スプレッドシートのどこかに完全な行がある場合は、nskip代わりにn. これにより、列推測の開始点が得られます。データ行 117 に完全なデータ セットがあるとします。

readxl:::xlsx_col_types(path = "a.xlsx", nskip = 116, n = 1)

名前空間で関数を編集しなくても、関数を直接呼び出すことができることに注意してください。

その後、スプレッドシート タイプのベクトルを使用して read_excel を呼び出すことができます。

col_types <- readxl:::xlsx_col_types(path = "a.xlsx", nskip = 116, n = 1)
dat <- readxl::read_excel(path = "a.xlsx", col_types = col_types)

次に、まだ間違っている列を手動で更新できます。

于 2015-11-01T13:14:57.953 に答える
2

sourceを確認すると、推測された列の型を返す Rcpp 呼び出しがあることがわかります。

xlsx_col_types <- function(path, sheet = 0L, na = "", nskip = 0L, n = 100L) {
    .Call('readxl_xlsx_col_types', PACKAGE = 'readxl', path, sheet, na, nskip, n)
}

nskip = 0L, n = 100Lデフォルトでは、最初の 100 行をチェックして列の型を推測することがわかります。nskip次のようにして、ヘッダー テキストを無視して増やすように変更できますn(ランタイムが大幅に遅くなります)。

col_types <-  .Call( 'readxl_xlsx_col_types', PACKAGE = 'readxl', 
                     path = file_loc, sheet = 0L, na = "", 
                     nskip = 1L, n = 10000L )

# if a column type is "blank", no values yet encountered -- increase n or just guess "text"
col_types[col_types=="blank"] <- "text"

raw <- read_excel(path = file_loc, col_types = col_types)

.Rcpp を見ないとnskip = 0L、ヘッダー行 (c++ カウントの 0 番目の行) をスキップするか、行をスキップしないかはすぐにはわかりません。nskip = 1Lデータセットの行をスキップしても、列の型の推測全体には影響しないため、を使用するだけであいまいさを回避しました。

于 2016-04-29T16:01:23.360 に答える
1

列タイプを推測するための内部関数は、スキャンする行数に設定できます。しかし、read_excel()それを実装していません (まだ?)。

以下の解決策は、デフォルトですべての行になるread_excel()引数を使用して元の関数を書き直したものです。n_max想像力の欠如のために、この拡張機能は と名付けられましread_excel2た。

すべての行で列の型を評価するにはread_excel、に置き換えるだけです。read_excel2

# Inspiration: https://github.com/hadley/readxl/blob/master/R/read_excel.R 
# Rewrote read_excel() to read_excel2() with additional argument 'n_max' for number
# of rows to evaluate in function readxl:::xls_col_types and
# readxl:::xlsx_col_types()
# This is probably an unstable solution, since it calls internal functions from readxl.
# May or may not survive next update of readxl. Seems to work in version 0.1.0
library(readxl)

read_excel2 <- function(path, sheet = 1, col_names = TRUE, col_types = NULL,
                       na = "", skip = 0, n_max = 1050000L) {

  path <- readxl:::check_file(path)
  ext <- tolower(tools::file_ext(path))

  switch(readxl:::excel_format(path),
         xls =  read_xls2(path, sheet, col_names, col_types, na, skip, n_max),
         xlsx = read_xlsx2(path, sheet, col_names, col_types, na, skip, n_max)
  )
}
read_xls2 <- function(path, sheet = 1, col_names = TRUE, col_types = NULL,
                     na = "", skip = 0, n_max = n_max) {

  sheet <- readxl:::standardise_sheet(sheet, readxl:::xls_sheets(path))

  has_col_names <- isTRUE(col_names)
  if (has_col_names) {
    col_names <- readxl:::xls_col_names(path, sheet, nskip = skip)
  } else if (readxl:::isFALSE(col_names)) {
    col_names <- paste0("X", seq_along(readxl:::xls_col_names(path, sheet)))
  }

  if (is.null(col_types)) {
    col_types <- readxl:::xls_col_types(
      path, sheet, na = na, nskip = skip, has_col_names = has_col_names, n = n_max
    )
  }

  readxl:::xls_cols(path, sheet, col_names = col_names, col_types = col_types, 
                    na = na, nskip = skip + has_col_names)
}

read_xlsx2 <- function(path, sheet = 1L, col_names = TRUE, col_types = NULL,
                       na = "", skip = 0, n_max = n_max) {
  path <- readxl:::check_file(path)
  sheet <-
    readxl:::standardise_sheet(sheet, readxl:::xlsx_sheets(path))

  if (is.null(col_types)) {
    col_types <-
      readxl:::xlsx_col_types(
        path = path, sheet = sheet, na = na, nskip = skip + isTRUE(col_names), n = n_max
      )
  }

  readxl:::read_xlsx_(path, sheet, col_names = col_names, col_types = col_types, na = na,
             nskip = skip)
}

この拡張された推測により、パフォーマンスに悪影響を及ぼす可能性があります。本当に大きなデータセットはまだ試していません。機能を検証するのに十分な小さなデータを試しただけです。

于 2016-02-16T18:32:27.707 に答える