@akrun 和 @Matt L. 的两个答案都很好地解决了问题。 @Matt L. 绝对是最简单的一个。谢谢。我在这里发布我根据 @akrun 的答案提出的解决方案。我肯定会在我的最终代码中使用 tidyr 。
library(htmlTable)
library(data.table)
library(Hmisc)
# Create input (initial) dataset (long)
region = c( "A", "A", "A", "B", "B", "B" )
week = c( "20", "21", "22", "20", "21", "22" )
average = c( 5, 7, 15, 4, 8, 3 )
percent = c( 30, 40, 50, 15, 27, 11 )
input_ds = data.frame(
region,
week,
average,
percent
)
# Reshape the dataset into wide, using columns average and percent
# for each week
reshaped_ds = dcast(
setDT( input_ds ),
region ~ week,
value.var = c("average", "percent")
)
# Extract the week number from each column and get a list of indices
# sorted by week number
col_order <- order(
as.numeric(
sub( ".*_", "", names( reshaped_ds )[-1] )
)
)
# Re-order columns according to col_order
setcolorder(
reshaped_ds, names(reshaped_ds)[c(1, col_order + 1)]
)
# Prepare the names for group columns
col_group_names = unique(
paste(
"Week",
sub( ".*_", "", names(reshaped_ds)[-1] )
)
)
# Create another dataset so we don't mess up the reshaped_ds
final_table_ds = reshaped_ds
# Remove '_##' from column names
names( final_table_ds ) = sub(
"_.*", "", names( final_table_ds )
)
# Capitalize the first letter of each column name
names( final_table_ds ) = capitalize( names( final_table_ds ) )
# Generate the final table in HTML
htmlTable(
final_table_ds,
rnames = FALSE,
cgroup = c( "", col_group_names ),
n.cgroup = c( 1, rep( 2, length(col_group_names) ) ),
col.rgroup = c( "none", "#EDEDED" )
)
最终输出: