【问题标题】:How check column existence in feather data file "before" reading in R?如何在 R 中“读取”之前检查羽毛数据文件中是否存在列?
【发布时间】:2020-03-09 14:09:23
【问题描述】:

我必须读取带有预定义列集的羽毛格式的数据文件。如果数据文件中不存在该列,则会生成错误。如何“在”读取数据集之前检查它

library(feather)

# 1. Data set
df_mtcars <- mtcars

# 2. Drop column
df_mtcars$mpg <- NULL

# 3. Save data
write_feather(df_mtcars, "df_mtcars")

# 4. How check column existance in file 'before' reading
if(!is.null(...)) {
  read_feather("df_mtcars", columns = c("mpg"))
}

谢谢!

【问题讨论】:

  • 不确定feather(从未使用过)但也许我们可以使用hasName(df_mtcars, "mpg")
  • 在内存读取“之前”检查文件级别是否存在列的问题
  • @Andrii feather 是二进制文件格式。如果您查看read_feather 的源代码,它会通过调用feather(path)整个 文件读入内存,然后选择您想要的列。所以你最好的选择是read_feather_column &lt;- function(path, column) {df &lt;- feather(path); if(hasName(data, column)) return(df[column])}

标签: r feather


【解决方案1】:

这是我为解决这个问题而设计的函数

#' Check if column exist in feather file
#' @param file_name path to the feather file
#' @param column_name name of column to check
#' @return logical value 'TRUE' if 'column_name' exist in file
is_column_feather_file <- function(file_name, column_name) {

  # 1. Init result
  result <- FALSE

  # 2. Read meta data and search for 'column_name'
  if(file.exists(file_name) & (column_name != "") & !is.null(column_name)) {

    # 2. 1. Meta data
    df_meta_data <- feather_metadata(file_name)

    # 2.2. Check if column exists
    result <- sum(names(df_meta_data$types) == column_name) == 1

  }

  # 3. Return result
  result

}


# Test
is_column_feather_file("mt_cars", "mpg")

【讨论】:

    【解决方案2】:

    feather 是二进制文件格式。如果您查看read_feather 的源代码,它会通过调用feather(path)整个 文件读入内存,然后选择您想要的列。看:

    read_feather
    #> function (path, columns = NULL) 
    #> {
    #>     data <- feather(path)
    #>     on.exit(close(data), add = TRUE)
    #>     if (is.null(columns)) 
    #>         as_tibble(data)
    #>     else as_tibble(data[columns])
    #> }
    #> <bytecode: 0x376de188>
    #> <environment: namespace:feather>
    

    (未压缩的)列名在文件中,但它们不在可靠的位置,因为它们出现在可变长度数据字段之后,所以没有办法只读取一小部分获取二进制文件的名称。

    所以最好的办法是做类似的事情,首先检查指定列是否存在:

    read_feather_column <- function(path, column) 
    {
      df <- feather(path)
      if(hasName(df, column)) 
        return(as_tibble(df[column]))
    }
    

    【讨论】:

    • 嗨,艾伦!感谢您的解决方案。请看看我的解决方案 - 我只是在文件读取之前读取元数据
    • 很好的解决方案@Andrii。但是,元数据函数仍然会在返回 TRUE 或 FALSE 之前将整个文件读入内存,因此使用您的方法对其进行检查将涉及将文件两次读入内存以获取您想要的数据(如果存在)。读取一次并返回数据(如果存在)会更快。
    猜你喜欢
    • 1970-01-01
    • 2021-06-12
    • 2021-06-06
    • 2021-05-31
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 2019-05-03
    • 1970-01-01
    相关资源
    最近更新 更多