在旋转更宽以导出到 xlsx 时使用 R 中的属性来保存元数据

Using attributes in R to hold metadata when pivoting wider for export to xlsx

我有一个看起来像这样的数据框:

df <- tribble(~date,      ~value, ~analyte, ~quantified,
              01-01-2020, 8.6,    Fe,       TRUE,
              02-06-2020, 10.4,   Ni,       TRUE,
              01-01-2020, 2,      Ni,       FALSE)

对于许多分析程序,存在量化(或检测或报告...)限制。量化列说明该值是高于还是低于此限制(T:高于,F:低于)。如果测试返回到量化限制以下,则量化限制被记录为值并且量化列设置为 FALSE。因此,对于第三行中的结果,量化限为 2 mg/L,样品中镍的真实值介于 0-2 mg/L 之间,但我们将其视为可能的最高值。

我需要将其转换为宽格式的 excel 电子表格(分析作为列名,每个日期一行),我想提供值低于量化限制的单元格样式,但不太明白如何。我正在考虑将量化作为属性添加到值单元格,然后应用基于该属性的 openxlsx 样式,但是 a) 我无法弄清楚如何将属性应用于值而不是整个列和 b) 我我不确定这是不是正确的方法。

下面是我的基本输出,但正如我所说,我不太明白如何以一种易于使用的方式将量化转换为宽格式,然后为单元格设置 xlsx 样式低于量化限度。

library(openxlsx)
df %>%
  dplyr::select(-quantification) %>%
  pivot_wider(id_cols = c(date), names_from = analyte, values_from = value) -> df
dfWorkbook <- createWorkbook()
addWorksheet(dfWorkbook, "test")
writeData(dfWorkbook, sheet = "test", x = df)

脚注:不幸的是,随着时间的推移,分析物之间的量化限制会发生变化,所以我不能只说“如果值 > 2,addStyle(dfWorkbook, “test”, BQL)”

我们需要做的就是使用 which(..., arr.ind=T) 让单元格索引在行组件中加一,以说明列名所做的偏移:

# keep the quantified vals in the same structure as the actual values
df %>%
  dplyr::select(-value) %>%
  pivot_wider(id_cols = c(date), names_from = analyte, values_from = quantified)  -> df.atts
df %>%
  dplyr::select(-quantified) %>%
  pivot_wider(id_cols = c(date), names_from = analyte, values_from = value) -> df
dfWorkbook <- createWorkbook()
addWorksheet(dfWorkbook, "test")
writeData(dfWorkbook, sheet = "test", x = df)

## create and add a style to the cells that verify condition
quantified <- createStyle(
  fontSize = 14, fontColour = "#FFFFFF", halign = "center",
  fgFill = "#4F81BD", border = "TopBottom", borderColour = "#4F81BD"
)
# get the cell indices that verify the condition
mat <-  which(df.atts == F, arr.ind = TRUE) 
# add the style for each cell in this matrix
addStyle(dfWorkbook, sheet = 1, headerStyle, rows = mat[,1]+1, cols = mat[,2])
# save the workbook
saveWorkbook(dfWorkbook, "styled.xlsx", overwrite = TRUE)