我有几十个excel文件,我想导入到R进行进一步的处理和分析。这些是每个月的文件。源文件带有过滤器,其中包括不需要的数据。我想使用readxl包中的read_xlsx函数。然而,所有行都被导入到R中,包括不需要的行。我知道我可以导入所有文件,然后做过滤的事情或只是复制粘贴原始excel文件。我想知道的是,在read_xlsx步骤中是否可以将过滤器保留在文件中,这是目前对我来说最好的选择。先谢谢你,菲利克斯
igetnqfo1#
除了@stefan的答案之外,还可以使用下面的openxlsx2找到一个。基本上,被筛选的行在工作表中是隐藏的。此信息存储在行中,通过openxlsx2导入,因此可用于跳过此类行。
openxlsx2
library(openxlsx2) tmp <- temp_xlsx() # create a file wb <- wb_workbook()$ add_worksheet()$add_data(x = mtcars, withFilter = TRUE)$ add_worksheet()$add_data_table(x = mtcars)$ save(tmp) # apply filter and save it (I choose mpg < 20 in `Sheet 1` and mpg > 20 in `Sheet 2`) xl_open(tmp)
字符串现在来回答这个问题:
# first sheet: mpg < 20 sheet1 <- wb_to_df(tmp, sheet = 1, skipHiddenRows = TRUE) head(sheet1) #> mpg cyl disp hp drat wt qsec vs am gear carb #> 6 18.7 8 360.0 175 3.15 3.44 17.02 0 0 3 2 #> 7 18.1 6 225.0 105 2.76 3.46 20.22 1 0 3 1 #> 8 14.3 8 360.0 245 3.21 3.57 15.84 0 0 3 4 #> 11 19.2 6 167.6 123 3.92 3.44 18.30 1 0 4 4 #> 12 17.8 6 167.6 123 3.92 3.44 18.90 1 0 4 4 #> 13 16.4 8 275.8 180 3.07 4.07 17.40 0 0 3 3 # second sheet: mpg > 20 sheet2 <- wb_to_df(tmp, sheet = 2, skipHiddenRows = TRUE) head(sheet2) #> mpg cyl disp hp drat wt qsec vs am gear carb #> 2 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 #> 3 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 #> 4 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 #> 5 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 #> 9 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2 #> 10 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
型PS:我们目前正在精简我们的API,并将支持snake case参数(尽管上面的代码仍然会运行)。
ne5o7dgx2#
不久前,我也在为同样的问题而挣扎。经过一些研究和AFAIK的简短回答是(仍然),这不能通过readxl实现。此外,AFAIK在openxlsx或...等软件包中也(仍然)没有开箱即用的选项。但是,由于openxlsx可以读取excel工作簿对象,因此它允许检索有关设置过滤器的信息,然后可以使用这些信息将过滤器应用于导入的数据集。下面的代码是如何实现这一点的一个示例。注意:代码在我的用例中工作得很好,但它并不意味着是一个通用的开箱即用的解决方案,因此您可能必须调整代码以满足您的需求。首先,让我们创建一个示例excel文件,我使用mtcars数据集:
readxl
openxlsx
mtcars
library(openxlsx) wb <- createWorkbook() addWorksheet(wb, "filter") writeDataTable(wb, "filter", mtcars) saveWorkbook(wb, "test-filter.xlsx")
字符串其次,在MS Excel中,我在表格上设置了两个过滤器,即我在cyl列上设置了一个过滤器,在carb列上设置了第二个过滤器:
cyl
carb
的数据下面的代码使用了一个自定义函数。
scrape_filter <- function(table) { x <- xml2::read_xml(table)|> xml2::xml_child(1)|> xml2::xml_children() col_id <- x|> xml2::xml_attrs()|> purrr::map_chr(1) vals <- purrr::map_chr(x, function(x) { xml2::xml_child(x, 1)|> xml2::xml_children()|> xml2::xml_attrs()|> purrr::map_chr(1)|> paste(collapse = "; ") }) data.frame(col_id, vals) |> select(col_id, vals) |> mutate(col_id = names(dat)[as.integer(.data$col_id) + 1]) |> mutate(filter_cond = if_else( .data$vals %in% "notEqual", glue::glue("!is.na({col_id})"), glue::glue('{col_id} %in% str_split("{vals}", "; ")[[1]]') )) }
型在加载数据和工作簿后,可以用它来提取设置过滤器的信息并解析它们...
library(tidyverse) library(xml2) library(readxl) library(openxlsx) library(glue) fn <- "test-filter.xlsx" dat <- readxl::read_xlsx(path = fn) wb <- loadWorkbook(fn) filters <- scrape_filter(wb$tables) R> filters col_id vals filter_cond 1 cyl 4; 8 cyl %in% str_split("4; 8", "; ")[[1]] 2 carb 2 carb %in% str_split("2", "; ")[[1]]
型...最后,在使用rlang::parse_exprs的导入数据集上应用过滤器
rlang::parse_exprs
filter(dat, !!!rlang::parse_exprs(filters$filter_cond)) # A tibble: 10 × 11 mpg cyl disp hp drat wt qsec vs am gear carb <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2 2 24.4 4 147. 62 3.69 3.19 20 1 0 4 2 3 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2 4 30.4 4 75.7 52 4.93 1.62 18.5 1 1 4 2 5 15.5 8 318 150 2.76 3.52 16.9 0 0 3 2 6 15.2 8 304 150 3.15 3.44 17.3 0 0 3 2 7 19.2 8 400 175 3.08 3.84 17.0 0 0 3 2 8 26 4 120. 91 4.43 2.14 16.7 0 1 5 2 9 30.4 4 95.1 113 3.77 1.51 16.9 1 1 5 2 10 21.4 4 121 109 4.11 2.78 18.6 1 1 4 2
型还有两个注意事项:
lapply
purrr::map
2条答案
按热度按时间igetnqfo1#
除了@stefan的答案之外,还可以使用下面的
openxlsx2
找到一个。基本上,被筛选的行在工作表中是隐藏的。此信息存储在行中,通过openxlsx2
导入,因此可用于跳过此类行。字符串
现在来回答这个问题:
型
PS:我们目前正在精简我们的API,并将支持snake case参数(尽管上面的代码仍然会运行)。
ne5o7dgx2#
不久前,我也在为同样的问题而挣扎。经过一些研究和AFAIK的简短回答是(仍然),这不能通过
readxl
实现。此外,AFAIK在openxlsx
或...等软件包中也(仍然)没有开箱即用的选项。但是,由于
openxlsx
可以读取excel工作簿对象,因此它允许检索有关设置过滤器的信息,然后可以使用这些信息将过滤器应用于导入的数据集。下面的代码是如何实现这一点的一个示例。
注意:代码在我的用例中工作得很好,但它并不意味着是一个通用的开箱即用的解决方案,因此您可能必须调整代码以满足您的需求。
首先,让我们创建一个示例excel文件,我使用
mtcars
数据集:字符串
其次,在MS Excel中,我在表格上设置了两个过滤器,即我在
cyl
列上设置了一个过滤器,在carb
列上设置了第二个过滤器:的数据
下面的代码使用了一个自定义函数。
型
在加载数据和工作簿后,可以用它来提取设置过滤器的信息并解析它们...
型
...最后,在使用
rlang::parse_exprs
的导入数据集上应用过滤器型
还有两个注意事项:
lapply
或purrr::map
来迭代表和工作表。