Объединение двух таблиц и добавление заголовка для каждой таблицы в R

Я хотел бы отобразить результаты двух регрессионных анализов рядом друг с другом, скажем, логистической и регрессии COX. Переменные представлены в строках, а соответствующие данные для p, OR/HR и доверительного интервала — в столбцах. Итак, имена столбцов не совпадают: слева ИЛИ, справа HR.

Я попробовал cbind, но столкнулся со следующими проблемами:

(1) Что делать, если одна переменная (строка) присутствует только в одной таблице из-за выбора переменной? В этом случае при их сочетании в другой таблице должна быть пустая строка.

(2) После того, как обе таблицы объединены, как вы можете добавить заголовок, охватывающий четыре столбца каждой таблицы, чтобы пометить их как логистические или COX?

Результат, который я ищу, должен отображаться в виде латексной таблицы через xtable:

   | Logistic regression          | COX regression
   | p     | OR    | 2.5% | 97.5% | p     | HR    | 2.5% | 97.5% 
v1 | 0.849 | 0.936 | ...  | ...   |       |       |      |
v2 | 0.249 | 0.595 | ...  | ...   | 0.026 | 1.916 | ...  | ...
v3 |       |       |      |       | 0.023 | 0.140 | ...  | ...

Вот пример кода:

library(xtable);library(survival)
# Creating a sample data frame
set.seed(1234)
event <- as.numeric(round(rnorm(10,5,5))>1);tte<-abs(round(rnorm(10,5,5)))
v1 <- round(rnorm(10,5,5));v2 <- round(rnorm(10,2,5));v3 <- round(rnorm(10,1,5))
df<-data.frame(event, tte, v1, v2, v3)

# Some logistic regression ...
LogReg <- glm(event~v1+v2,family=binomial,data=df)
LogRegTable<-round(cbind(summary(LogReg)$coef[, "Pr(>|z|)"], exp(coef(LogReg)),   exp(confint(LogReg))),3)
colnames(LogRegTable)<-c("p","OR","2.5%","97.5%")
LogRegTable<-LogRegTable[!rownames(LogRegTable)=="(Intercept)",] 

# ... and some COX regression
CoxReg <- coxph(Surv(df$tte, df$event)~v2+v3,data=df)
CoxRegTable<-round(cbind(summary(CoxReg)$coef[, "Pr(>|z|)"], exp(coef(CoxReg)),  exp(confint(CoxReg))),3)
colnames(CoxRegTable)<-c("p","HR","2.5%","97.5%")

# There we go
LogRegTable
CoxRegTable

# Now, how to get them in one table?
xtable(
  cbind(LogRegTable, CoxRegTable)
)
# ... messes up the correct row names   

person moabit21    schedule 07.06.2014    source источник
comment
Если вы хотите сопоставлять бок о бок на основе имен переменных, merge() будет лучше, чем cbind. Если вам нужны причудливые таблицы, рассмотрите возможность использования пакета, такого как xtables или stargazer, для создания вывода LaTeX (или напишите код, чтобы сделать LaTeX именно таким, как вы хотите). Здесь просто недостаточно информации, чтобы дать более конкретные рекомендации (рассмотрите возможность добавления примеров данных и кода, который вы пробовали).   -  person MrFlick    schedule 07.06.2014
comment
Спасибо. На самом деле, я хочу передать окончательный вывод через xtable, чтобы он хорошо выглядел в LaTex. Когда я использую слияние (), как я могу указать соответствие через имена переменных, то есть первый столбец? Список имен столбцов с именами столбцов (LogRegTable) начинается с p, поэтому второй столбец.   -  person moabit21    schedule 09.06.2014


Ответы (4)


Как предлагает MrFlick, вы можете сделать это с помощью функции merge() более эффективно, чем с помощью cbind.

Вы можете использовать merge() следующим образом:

xtable <- merge(LogRegTable, CoxRegTable, by.x = "p", by.y = "p", all = TRUE)

В этом случае by.x и by.y ссылаются на столбец, который вы хотите объединить. Если имя столбца одинаково в обеих таблицах (как в этом случае), вы можете просто использовать by = "p", но этот метод (с by.x и by.y) позволяет объединить два разных заголовка столбца.

All = TRUE заставит объединенную таблицу сохранить все строки из обеих таблиц, даже если они обе не имеют общего значения для p. Если вы измените это значение на FALSE, то будут удалены все строки со значением p, которого нет в обеих таблицах.

Если вы хотите переименовать имена столбцов после (хотя ваши имена столбцов должны были быть сохранены удовлетворительно), вы можете использовать colnames() следующим образом:

colnames(xtable) <- c("col1_name", "col2_name", etc)
person Meaghan Fitzgerald    schedule 10.06.2014

Вот как бы я это сделал:

#Add column for variable name 
LogRegTable <- cbind(v = rownames(LogRegTable), LogRegTable)
CoxRegTable <- cbind(v = rownames(CoxRegTable), CoxRegTable)

#merge on variable name
bothTable <- merge(LogRegTable, CoxRegTable, by = "v", all = TRUE)

#create an xtable object
forLatex <- xtable(bothTable)

#remove rownames and formatting details which I personally prefer to set up in my actual latex code.
#customize based on ?print.xtable to fit your needs
#and write the table to a text file
cat( print.xtable(forLatex, include.colnames = FALSE, include.rownames = FALSE, only.contents = TRUE), file = "latextable.txt")

Надеюсь, это поможет.

person WheresTheAnyKey    schedule 12.06.2014

R на самом деле не выполняет "двойной заголовок", о котором вы просите (где имена столбцов могут быть сгруппированы под именем заголовка), но это даст вам что-то управляемое:

Вам нужно будет преобразовать в data.frame, чтобы это сработало, что означает, что ваши имена столбцов, начинающиеся с цифры, получат X перед ними. Вы можете изменить это позже для xtable. Вы должны добавить столбец, который идентифицирует переменную:

> LogRegTable = data.frame(LogRegTable, Variable = rownames(LogRegTable))
> CoxRegTable = data.frame(CoxRegTable, Variable = rownames(CoxRegTable))
> LogRegTable
       p    OR X2.5. X97.5. Variable
v1 0.849 0.936 0.433  2.018       v1
v2 0.249 0.595 0.129  0.995       v2
> CoxRegTable
       p    HR X2.5. X97.5. Variable
v2 0.026 1.916 1.080  3.402       v2
v3 0.023 0.140 0.025  0.766       v3  

Тогда это простая операция слияния:

> merge(LogRegTable, CoxRegTable, by="Variable", all=T, suffixes = c("Log", "Cox"))
  Variable  pLog    OR X2.5.Log X97.5.Log  pCox    HR X2.5.Cox X97.5.Cox
1       v1 0.849 0.936    0.433     2.018    NA    NA       NA        NA
2       v2 0.249 0.595    0.129     0.995 0.026 1.916    1.080     3.402
3       v3    NA    NA       NA        NA 0.023 0.140    0.025     0.766
person Señor O    schedule 12.06.2014

Если вы в конечном итоге выводите латексную таблицу. Вам не нужно отделять вывод R от латекса. Я рекомендую использовать knitr. Как упоминалось выше, вывод латекса можно настроить с помощью Stargazer или xtable. Тем не менее, с моей точки зрения, texreg более эффективен, чем звездочет, и его легче настроить, чем xtable. Тем не менее, я не могу воспроизвести точно такой же формат, который вам требуется, поскольку кажется, что p-значения не доступны напрямую. Но доверительный интервал помечается звездочкой, если оценка выходит за пределы доверительного интервала.

предыдущая версия

texreg не вычисляет коэффициенты нечетности напрямую, но его легко настроить. После загрузки пакета texreg вы можете получить доступ к функциям извлечения, набрав. (Если вы предпочитаете журнал шансов, вы можете сразу перейти к строке И мы готовы к работе)

extract.glm и extract.coxph в командной строке

и скопировать его в свой скрипт. Тогда нам нужно только изменить

coefficients <- s$coef[, 1] into coefficients <- exp(s$coef[, 1]) для обеих функций.

Также хорошо переименовать функции на случай, если что-то пойдет не так. Я выбрал

extract.coxphOR и extract.glmOR

После запуска функции мы должны указать texreg использовать нашу модифицированную функцию вместо обычных.

 setMethod("extract", signature = className("glm","stats"),definition = extract.glmOR)
 setMethod("extract", signature = className("coxph","survival"),definition = extract.coxphOR)

И мы готовы идти:

texreg(list(LogReg,CoxReg),ci.force = T,single.row=T,ci.force.level=0.025,custom.model.names = c("Logistic Regression", "Cox Regression"))

обновленная версия, предложенная в комментарии, отношение шансов может быть вычислено более простым способом. Хотя предыдущая версия неэффективна, я оставляю ее на случай, если кому-то понадобится изменить функцию извлечения.

texreg(list(LogReg,CoxReg),ci.force = TRUE, single.row = TRUE, ci.force.level = 0.025,    custom.model.names = c("Logistic Regression", "Cox Regression"), override.coef = list(exp(coef(LogReg)), exp(coef(CoxReg))))

Результаты:

\begin{table}
\begin{center}
\begin{tabular}{l c c }
\hline
           & Logistic Regression & Cox Regression \\
\hline
(Intercept)    & $1.77 \; [1.72;\ 1.82]^{*}$ &                             \\
v1             & $0.94 \; [0.92;\ 0.95]^{*}$ &                             \\
v2             & $0.59 \; [0.58;\ 0.61]^{*}$ & $1.92 \; [1.91;\ 1.93]^{*}$ \\
v3             &                             & $0.14 \; [0.11;\ 0.17]^{*}$ \\
\hline
AIC            & 13.63                       & 17.36                       \\
BIC            & 14.54                       &                             \\
Log Likelihood & -3.82                       &                             \\
Deviance       & 7.63                        &                             \\
Num. obs.      & 10                          & 10                          \\
R$^2$          &                             & 0.68                        \\
Max. R$^2$     &                             & 0.92                        \\
Num. events    &                             & 7                           \\
Missings       &                             & 0                           \\
PH test        &                             & 0.90                        \\
\hline
\multicolumn{3}{l}{\scriptsize{$^*$ 0 outside the confidence interval}}
\end{tabular}
\caption{Statistical models}
\label{table:coefficients}
\end{center}
\end{table}
person DJJ    schedule 12.06.2014
comment
Вам даже не придется переопределять методы Extract.glm и Extract.coxph. Достаточно вызвать команду texreg, как описано в вашем ответе, и использовать аргумент override.coef для предоставления преобразованных коэффициентов. Вы могли бы в основном сделать все это в одной строке кода. - person Philip Leifeld; 29.06.2014
comment
насколько я понял override.coef не вычисляет отношение шансов. Если нет, то вам нужно вычислить шансы, поместить их в массив и использовать переопределить коэф. - person DJJ; 30.06.2014
comment
Да, это почти все. Но вы можете сделать это в той же строке кода. Ваш модифицированный пример: texreg(list(LogReg,CoxReg),ci.force = TRUE, single.row = TRUE, ci.force.level = 0.025, custom.model.names = c("Logistic Regression", "Cox Regression"), override.coef = list(exp(coef(LogReg)), exp(coef(CoxReg)))) - person Philip Leifeld; 30.06.2014