2017-02-02 8 views
0

私はRを学んでいます。簡単で読みやすいRコードを使って出版物の要約統計表を作成したいと思います。テーブルには行として変数があり、平均とSDが列として交互に表示され、2つのグループ化変数も列として表示されます。すべての値はゼロを含めて2桁に丸めます(必要に応じてゼロを追加します)。複数の変数の平均と標準偏差を、グループごとに公表用にフォーマットしました。

例として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) | 

私は、次のコードを書きましたが、私最初の2つの行を作成し、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"列は正しく丸められません。私はパンダを試しましたが、ゼロを追加することはできません。

|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の最初の関数に取り入れた答えを提供しました。私はここで更新していますので、他の人がこの関数を修正して使うことができます。これにはまだ数字と1つ以上の数字が指定されている場合があります。

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

あなたは2桁が小数点以下の後にあることを確認することができるようにformatを使用して文字クラスに各列を変換してから、これは非常に便利です、あなたのかっこで

#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

を追加し、あなたに感謝することができます!列名の行を修正する方法もわかりました。 '#rename columns setnames(outputTbl、colnames(outputTbl)、gsub(" variable "、" "、gsub(" sd "、" "(gsub("平均 "、" "、 "、" "、colnames(means_sd_dt))))))))' –

+0

私はこれを関数にして、さまざまな出版物に使うことができます。値を手で指定するのではなく、myColsを参照するように、 'means_sd_dt < - dcast.data.table(means_sd_merged_dt、variable〜cyl + am + stat、value.var =" value ")'行を修正する方法はありますか? –

+0

Rのすぐ前には、「as.formula」があります。 – chinsoon12

関連する問題