2017-02-02 12 views
0

Я изучаю 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) 
} 

ответ

1

Вы можете преобразовать каждый столбец в класс символов, используя format, так что вы можете быть уверены, что есть 2 цифры после знака после запятой, а затем добавьте в ваших скобках

#ensure there are 2 digits after decimal 
cols <- setdiff(names(means_sd_dt), "variable") 
means_sd_dt[, (cols) := lapply(.SD, format, digits=2, nsmall=2L, 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 first row 
outputTbl <- rbindlist(list(
    data.table(t(c("", rep(c("mean", "(SD)"), (ncol(means_sd_dt)-1)/2)))), 
    means_sd_dt), use.names=FALSE) 

kable(outputTbl, digits = 2) 
+0

Это очень полезно, спасибо ! Я также выяснил, как исправить строку имен столбцов. '#ename columns setnames (outputTbl, colnames (outputTbl), gsub (" variable "," ", (gsub (" sd "," ", (gsub (" mean "," ", (gsub (" _ "," ", colnames (means_sd_dt)))))))))' –

+0

Я хочу сделать это функцией, чтобы я мог использовать ее для различных публикаций. Есть ли способ исправить строку 'mean_sd_dt <- dcast.data.table (mean_sd_merged_dt, variable ~ cyl + am + stat, value.var =" значение ")', чтобы она ссылалась на myCols вместо указания их вручную? –

+0

Теперь не перед R, проверьте 'as.formula'. – chinsoon12