如何按列位置而非列名动态mutate R语言数据框列
按列位置动态设置R数据框的单元格样式
问题背景
现有如下R数据框:
data <- structure(list(Category = c("Food", "Alcoholic B&T", "Clothing", "Housing", "Furnishings", "Health", "Transport", "Communication", "Recreation", "Education", "Hotels", "Miscellaneous", "All items" ), Weight = c(" 16.4", " 12.6", " 3.0", " 28.4", " 5.5", " 2.0", " 14.3", " 3.8", " 3.6", " 3.6", " 1.4", " 5.4", "100.0" ), `*Jul 2023` = c("10.5", " 6.9", " 1.8", " 2.7", " 7.0", " 4.1", "-2.5", " 0.6", " 9.9", " 3.8", " 5.3", " 5.6", " 4.5"), `*Aug 2023` = c("10.5", " 6.9", " 1.2", " 2.4", " 6.9", " 4.1", "-2.4", " 1.0", " 9.6", " 3.8", " 5.0", " 5.3", " 4.5"), `*Sep 2023` = c("10.3", " 6.6", " 1.4", " 2.3", " 6.3", " 3.9", "-0.8", " 0.6", " 9.4", " 3.8", " 4.8", " 4.9", " 4.6"), `*Oct 2023` = c("11.5", " 6.6", " 1.1", " 2.2", " 6.1", " 3.2", "-0.8", " 0.9", " 9.7", " 3.8", " 4.6", " 4.9", " 4.7"), `**Aug 2023` = c("10.1", " 6.9", " 1.2", " 2.8", " 6.9", " 4.1", "-2.7", " 1.0", " 9.6", " 3.8", " 5.0", " 5.3", " 4.4"), `**Sep 2023` = c("10.4", " 6.6", " 1.4", " 2.6", " 6.3", " 3.9", "-1.1", " 0.6", " 9.4", " 3.8", " 4.8", " 4.9", " 4.6" ), `**Oct 2023` = c("11.6", " 6.6", " 1.1", " 2.5", " 6.1", " 3.2", "-1.1", " 0.9", " 9.7", " 3.8", " 4.6", " 4.9", " 4.8")), row.names = c(NA, -13L), class = c("tbl_df", "tbl", "data.frame"))
需要给位置7-9的列设置单元格背景色:当该列值与位置4-6对应列的值相等时,背景为白色;否则为#c7af76。目前已通过指定列名实现,现需改为按列位置动态实现,无需硬编码列名。
解决方案
可以使用tidyverse中的across()函数,结合列位置索引来动态处理:
library(tidyverse) library(kableExtra) data %>% mutate(across(7:9, .names = "{col}", ~cell_spec(., background = ifelse(. == pull(., .index - 3), 'white', '#c7af76'))))
代码说明
across(7:9):指定要处理的目标列(数据框中第7到第9列).index:across()中内置的参数,返回当前列在数据框中的位置索引.index - 3:计算出对应参照列的位置(第7列对应第4列,第8列对应第5列,第9列对应第6列)pull(., .index - 3):提取参照列的数值,与当前列的值进行比较cell_spec():根据比较结果设置单元格背景色,相等时用白色,否则用指定的棕黄色
由于原始数据中的数值列均为字符类型,直接用==比较即可;如果后续转换为数值类型,只需确保两列数据类型一致,比较逻辑无需调整。
内容的提问来源于stack exchange,提问作者Tanga94
相关产品推荐
相关产品推荐

