我正在嘗試使用modelsummary 創建一個包含因子和數字變數的表。我這樣做的方法是將因子變數轉換為數字,以便每個因子變數只出現 1 行,并且所有變數都出現在同一列中。然后,我將手動計算每個先前因子/現在數字變數的每個級別的單位數??,并將其作為文本分配給我資料集中的每個變數。我正在嘗試按照N_alt以下示例中呼叫的函式執行此操作:
library(modelsummary)
library(kableExtra)
tmp <- mtcars[, c("mpg", "hp")]
tmp$class <- 0
tmp$class[15:32] <- 1
tmp$class <- as.factor(tmp$class)
tmp$region <- 1
tmp$region[15:20] <- 2
tmp$region[21:32] <- 3
tmp$region <- as.factor(tmp$region)
tmp$class <- 0
tmp$region <- 0
N_alt = function(x) {
if (x %in% c(tmp$class)) {
paste0('[14 (43.8); 18 (56.3)]')
} else if (x %in% c(tmp$region)) {
paste0('[14 (43.8); 6 (18.8); 12 (37.5)]')
} else {
paste0('[32 (100)]')
}
}
# create a table with `datasummary`
emptycol = function(x) " "
datasummary(mpg (`class [0,1]`= class) (`region [A,B,C]`= region) hp ~ Heading("N (%)") * N_alt, data = tmp)
這給了我:

我的N_alt功能不能正常作業。class是正確的,但region不是。我沒有收到任何警告訊息。
我也試過:
N_alt = function(x) {
if (x[1] %in% c(tmp$class)) {
paste0('[14 (43.8); 18 (56.3)]')
} else if (x[1] %in% c(tmp$region)) {
paste0('[14 (43.8); 6 (18.8); 12 (37.5)]')
} else {
paste0('[32 (100)]')
}
}
但我獲得了相同的輸出。我用這些向量創建了類似的函式,它們運行良好,但由于某種原因,這個函式不起作用。
Additionally, I also tried:
N_alt <- c('[32 (100)]','[14 (43.8); 18 (56.3)]','[14 (43.8); 6 (18.8); 12 (37.5)]','[32 (100)]')
and
N_alt <- c(rep('[32 (100)]',32),rep('[14 (43.8); 18 (56.3)]',32),rep('[14 (43.8); 6 (18.8); 12 (37.5)]',32),rep('[32 (100)]',32))
but I get:
Error in datasummary(mpg (`class [0,1]` = class) (`region [A,B,C]` = region) :
Argument 'N_alt' is not length 32
Does anyone know what I am missing here?
Edit:
It seems to be possible to run functions just as the below Mean_alt so that certain numeric variables do not have decimal places (just converting them to as.integer did not work for me) and previously factor/now numeric variables do not show any results for Mean in the table (two different actions), as per the below:
library(modelsummary)
library(kableExtra)
tmp <- mtcars[, c("mpg", "hp")]
tmp$class <- 0
tmp$class[15:32] <- 1
tmp$class <- as.factor(tmp$class)
tmp$region <- 1
tmp$region[15:20] <- 2
tmp$region[21:32] <- 3
tmp$region <- as.factor(tmp$region)
tmp$class <- 0
tmp$region <- 0
N_alt = function(x) {
if (x %in% c(tmp$class)) {
paste0('[14 (43.8); 18 (56.3)]')
} else if (x %in% c(tmp$region)) {
paste0('[14 (43.8); 6 (18.8); 12 (37.5)]')
} else {
paste0('[32 (100)]')
}
}
Mean_alt = function(x) {
if (x %in% c(tmp$mpg)) {
as.character(floor(mean(x)), length=5)
} else if (x %in% c(tmp$class, tmp$region)) {
paste0("")
} else {
mean(x)
}
}
# create a table with `datasummary`
emptycol = function(x) " "
datasummary(mpg (`class [0,1]`= class) (`region [A,B,C]`= region) hp ~ Heading("N (%)") * N_alt Heading("Mean") * Mean_alt, data = tmp)
output:

uj5u.com熱心網友回復:
您正面臨三個限制。
第一個限制是 Base R:
- 正如
R手冊中所解釋的,if/ 中的陳述句else必須評估為單個TRUE或FALSE。在內部,datasummary將N_alt一個接一個地應用于每個變數。每次,N_alt接收一個長度為 32 的新向量。坦率地說,我認為檢查該向量的第一個元素的值沒有多大意義;我不明白這怎么能讓我們到達我們想去的地方。
另外兩個限制與tables包的基本設計有關,它modelsummary::datasummary基于:
- 因子將始終為每個因子級別生成一行。
- 我不認為有什么好方法可以說明
datasummary一個函式在應用于不同的數字變數時應該表現出不同的行為。這是因為每個函式只能看到原始數字向量,而不是其他元資訊。
我認為最簡單的解決方法是創建兩個表,一個用于您的因子,另一個用于您的數字。然后,這些表可以很容易地組合起來:
library(modelsummary)
N_factor <- function(x) {
count <- table(x)
pct <- prop.table(count)
out <- paste(sprintf("%.0f (%.1f)", count, pct), collapse = "; ")
sprintf("[%s]", out)
}
N_numeric <- function(x) {
sprintf("%s (100)", length(x))
}
tab_fac <- datasummary(cyl gear ~ Heading("N") * N_factor,
output = "data.frame",
data = mtcars)
datasummary(mpg hp ~ Heading("N") * N_numeric,
add_rows = tab_fac,
data = mtcars)
| N | |
|---|---|
| 英里 | 32 (100) |
| 生命值 | 32 (100) |
| 圓柱 | [11 (0.3); 7 (0.2); 14 (0.4)] |
| 齒輪 | [15 (0.5); 12 (0.4); 5 (0.2)] |
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/351965.html
