Я изучаю R. Я хочу составить сводную таблицу статистики для публикации с использованием простого, читаемого R-кода. В таблице должны быть переменные как строки, среднее среднее и SD как столбцы, а также две переменные группировки также как столбцы. Все значения должны округляться до двух цифр, включая нули (при необходимости добавляя нули).Создать таблицу средних значений и (стандартные отклонения) для нескольких переменных по группам, отформатированных для публикации
Использование mtcars набора данных в качестве примера, я хочу, чтобы таблица выглядеть сравнение 4, 6 и 8 цилиндровых автомобилей, автоматический или ручной):
| |4 0 | |4 1 | |6 0 | |6 1 | |8 0 | |8 1 | |
|:----|:---------|:-------|:---------|:-------|:---------|:-------|:---------|:-------|:---------|:-------|:---------|:-------|
| |mean |(SD) |mean |(SD) |mean |(SD) |mean |(SD) |mean |(SD) |mean |(SD) |
|mpg |22.90 |(1.45) |28.07 |(4.48) |19.12 |(1.63) |20.57 |(0.75) |15.05 |(2.77) |15.40 |(0.57) |
|disp |135.87 |(13.97) |93.61 |(20.48) |204.55 |(44.74) |155.00 |(8.66) |357.62 |(71.82) |326.00 |(35.36) |
|hp |84.67 |(19.66) |81.88 |(22.66) |115.25 |(9.18) |131.67 |(37.53) |194.17 |(33.36) |299.50 |(50.20) |
Я написал следующий код, но я все же необходимо создать первые две строки и добавить скобки к столбцам SD. Чтобы сделать таблицу симпатичной для публикации, я использовал R Markdown, knitr и kable. Есть ли более простой, более стандартный или более идиоматический способ сделать это?
```{r Create-Table-1}
library(data.table)
library(knitr)
mtcars_dt <- data.table(mtcars)
myGroups <- c("cyl", "am")
myVariables <- c("mpg", "disp", "hp")
means_dt <- mtcars_dt[,lapply(.SD, mean), .SDcols = myVariables, by = myGroups]
means_dt.melted <- melt.data.table(means_dt, id.vars = myGroups, measure.vars = myVariables)
means_dt.melted$stat <- "mean"
sd_dt <- mtcars_dt[,lapply(.SD, sd), .SDcols=myVariables, by=myGroups]
sd_dt.melted <- melt.data.table(sd_dt, id.vars = myGroups, measure.vars = myVariables)
sd_dt.melted$stat <- "sd"
means_sd_merged_dt <- rbindlist(list(means_dt.melted, sd_dt.melted))
means_sd_dt <- dcast.data.table(means_sd_merged_dt, variable ~ cyl + am + stat, value.var = "value")
kable(means_sd_dt, digits = 2)
```
Это таблица, которую производит код. Столбец «8_1_mean» не округлен правильно. Я попробовал pander, но он не может добавить нули.
|variable | 4_0_mean| 4_0_sd| 4_1_mean| 4_1_sd| 6_0_mean| 6_0_sd| 6_1_mean| 6_1_sd| 8_0_mean| 8_0_sd| 8_1_mean| 8_1_sd|
|:--------|--------:|------:|--------:|------:|--------:|------:|--------:|------:|--------:|------:|--------:|------:|
|mpg | 22.90| 1.45| 28.07| 4.48| 19.12| 1.63| 20.57| 0.75| 15.05| 2.77| 15.4| 0.57|
|disp | 135.87| 13.97| 93.61| 20.48| 204.55| 44.74| 155.00| 8.66| 357.62| 71.82| 326.0| 35.36|
|hp | 84.67| 19.66| 81.88| 22.66| 115.25| 9.18| 131.67| 37.53| 194.17| 33.36| 299.5| 50.20|
UPDATE: Одна из главных причин, почему я отвечал на этот вопрос в том, чтобы увидеть, если есть более простой и легкий способ сделать этот вид таблицы, с помощью других библиотек и программирования передового опыта.
Однако chinsoon12 предоставил ответ, который работает, который я включил в свою первую функцию в R. Я обновляю здесь, чтобы другие люди могли изменять и использовать эту функцию. У него все еще есть ошибка, которую я не могу записать с цифрами и/или nsmall, где иногда подгруппа будет иметь еще одну цифру, чем указано.
tabulatemsg <- function(variables, groups, input_dt, round_digits = 2, na.rm = FALSE) {
# Create a table of alternating means and (SDs), for the specified variables, with groups as columns.
require(data.table)
# Aggregate means
means_dt <- input_dt[,lapply(.SD, mean, na.rm = na.rm), .SDcols = variables, by = groups]
means_dt.melted <- melt.data.table(means_dt, id.vars = groups, measure.vars = variables)
means_dt.melted$stat <- "mean"
# Aggregate standard deviations
sd_dt <- input_dt[,lapply(.SD, sd, na.rm = na.rm), .SDcols=variables, by=groups]
sd_dt.melted <- melt.data.table(sd_dt, id.vars = groups, measure.vars = variables)
sd_dt.melted$stat <- "sd"
# Merge and cast
means_sd_merged_dt <- rbindlist(list(means_dt.melted, sd_dt.melted))
means_sd_dt <- dcast.data.table(means_sd_merged_dt, paste("variable",
paste(c(groups, "stat"), collapse=" + "), sep=" ~ "), value.var = "value")
# Ensure there are the specified number of digits after the decimal
cols <- setdiff(names(means_sd_dt), "variable")
means_sd_dt[, (cols) := lapply(.SD, format, digits=round_digits, nsmall=round_digits, justify="none"), .SDcols=cols]
means_sd_dt[, (cols) := lapply(.SD, trimws), .SDcols=cols]
# Add in parentheses
cols <- names(means_sd_dt)[seq(3, ncol(means_sd_dt), by=2)]
means_sd_dt[, (cols) := lapply(.SD, function(x) paste0("(", x, ")")), .SDcols=cols]
# Add in second row
output_table <- rbindlist(list(
data.table(t(c("", rep(c("Mean", "(SD)"), (ncol(means_sd_dt)-1)/2)))),
means_sd_dt), use.names=FALSE)
# Rename first row
setnames(output_table, colnames(output_table),
gsub("variable", "", (gsub(" sd","", (gsub(" mean", "", (gsub("_"," ", colnames(means_sd_dt)))))))))
return(output_table)
}
Это очень полезно, спасибо ! Я также выяснил, как исправить строку имен столбцов. '#ename columns setnames (outputTbl, colnames (outputTbl), gsub (" variable "," ", (gsub (" sd "," ", (gsub (" mean "," ", (gsub (" _ "," ", colnames (means_sd_dt)))))))))' –
Я хочу сделать это функцией, чтобы я мог использовать ее для различных публикаций. Есть ли способ исправить строку 'mean_sd_dt <- dcast.data.table (mean_sd_merged_dt, variable ~ cyl + am + stat, value.var =" значение ")', чтобы она ссылалась на myCols вместо указания их вручную? –
Теперь не перед R, проверьте 'as.formula'. – chinsoon12