我有很多长Excel文件,手动处理它们太难了。我在 R 中阅读它们以识别图像中突出显示的黄色单元格
目标:循环遍历文件中的天数和小时数,以构建一个数据框,根据小时数指示选项 as
我正在关注这些答案:answer1,answer2,answer3使用图书馆
xlsx
,openxlsx
和tidyr
完成工作
library(xlsx)
library(openxlsx)
library(tidyr)
wb <- loadWorkbook("active.xlsx") #the table is saved in the file active.xlsx
sheet1 <- getSheets(wb)[[1]]
rows <- getRows(sheet1)
cells <- getCells(rows)
styles <- sapply(cells, getCellStyle)
cellColor <- function(style)
{
fg <- style$getFillForegroundXSSFColor()
rgb <- tryCatch(fg$getRgb(), error = function(e) NULL)
rgb <- paste(rgb, collapse = "")
return(rgb)
}
mycolor <- (yellow = "ffff00")
m <- match(sapply(styles, cellColor), mycolor)
但是数据既没有被正确读取也没有被正确处理并且代码没有产生所需的结果,我什至没有接近!
是否有可能指导我并链接 R 中的教程或包,我可以使用它来检测突出显示的单元格并构建所需的数据框?
查看免费在线书籍“电子表格加工策略”:
https://nacnudus.github.io/spreadsheet-munging-strategies/ 使用 tidyxl 包。
如果是有色细胞:
https://nacnudus.github.io/spreadsheet-munging-strategies/tidy-formatted-cells.html
我制作了一个 excel 文件,类似于显示的名为 openxlsx highlighted cell.xlsx
使用 openxlsx,创建一个工作簿,然后加载现有的“openxlsx highlighted cell.xlsx”。这将保留 excelworkbook 的格式,但不会读取数据。如果使用 RStudio IDE,您可以查看工作簿中的现有样式
library(tidyverse)
library(openxlsx)
wb <- createWorkbook()
wb <- openxlsx::loadWorkbook(file = "path_to_file\\openxlsx highlighted cell.xlsx",isUnzipped = F)
wb$styleObjects #shows all styles
看样式,第二个样式有rgb值表示的黄色高亮单元格,它还列出了这种格式的单元格对应的行和列坐标。
接下来制作行和列的向量,后面会用到
highlighted_rows <- wb$styleObjects[[2]]$rows
highlighted_cols <- wb$styleObjects[[2]]$cols
接下来,将数据作为单独的工作簿读入,这将读入 excel 中显示的数据。由于其中一个是合并单元格并且对您的约会很重要,因此指定应该填充合并单元格。这将使您能够跟踪日期/选项组合。将 colnames 设置为 FALSE,因为第一行将用作数据而不是列名
wb_read <- createWorkbook()
wb_read <- readWorkbook(xlsxFile = "path_to_file\\openxlsx highlighted cell.xlsx",fillMergedCells = T,colNames = FALSE)
Excel 不喜欢时间行,所以我不得不重写时间值(也将 12:30:00 转换为 00:30:00),但这可能是由于我最初格式化 excel 的方式所致
times <- seq(from=as.POSIXct("2005-02-05 00:30:00"),to=as.POSIXct("2005-02-05 09:30:00"),by="30 min") %>%
substr(start = 12, stop = 20)
wb_read[1,3:21] <- times
仅将此应用于第一行,因为第 15 行与第 1 行的时间重复
您基本上需要时间和选项在各自系列中所处位置的索引。所以我们制作了两个向量,一个有时间位置——这将包括没有时间值的初始 A 和 B 列
times_positions <- wb_read[1,]
times_positions <- times_positions %>%
t()
类似地,选项值是和日期值(这是用早期代码填充的合并单元格)
option_index <- wb_read %>%
pull(X2)
date_index <- wb_read %>%
pull(X1)
由于您还想在没有突出显示的单元格的情况下保留 NA 值或时间,因此您还需要一个扩展的数据集,以便稍后加入突出显示的单元格数据。这段代码可以用一个函数来改进,但我保留原样用于演示/只有 2 个日期:
date1 <- seq(from=as.POSIXct("2005-01-05 00:30:00"),to=as.POSIXct("2005-01-05 09:30:00"),by="30 min")
date2 <- seq(from=as.POSIXct("2005-02-05 00:30:00"),to=as.POSIXct("2005-02-05 09:30:00"),by="30 min")
date1 <- as_tibble(date1) %>%
set_names("X")
date2 <- as_tibble(date2) %>%
set_names("X")
all_date_times <- bind_rows(date1,date2)
然后它只是将突出显示的行/单元格汇集在一起,索引向量应该是什么,并与所有组合结合以确定哪里会有 NA 突出显示。
df <- as_tibble(bind_cols(highlighted_rows,highlighted_cols)) %>%
set_names("rows", "columns") %>%
mutate(Option = option_index[rows],
time = times_positions[columns],
date = mdy(date_index[rows])) %>% #change to date here
dplyr::select(Option, time, date) %>%
mutate(date_time = paste(date,time) %>% strptime(.,format = "%Y-%m-%d %H:%M:%S")) %>%
right_join(all_date_times, by = c("date_time" = "X")) %>%
arrange(date_time) %>%
dplyr::select(date_time, Option) %>%
rename("Date" = "date_time")
df %>%
View()