2014-07-03 16 views
11

Sto usando xtable per generare tabelle da inserire in Latex e mi chiedevo se c'è un modo per avere la formattazione condizionale delle celle in modo che tutti i valori p significativi siano in grigio ? Sto usando Knitr in TexShop.xtable per la formattazione di celle condizionali significativi p-valori della tabella

Ecco un esempio utilizzando i dati diamonds in ggplot2 ed eseguendo un test TukeyHSD per prevedere carat da cut.

library(ggplot2) 
library(xtable) 
summary(data.aov <- aov(carat~cut, data = diamonds)) 
data.hsd<-TukeyHSD(data.aov) 
data.hsd.result<-data.frame(data.hsd$cut) 
data.hsd.result 

posso quindi ottenere data.hsd.result in formato XTABLE con:

xtable(data.hsd.result) 

In Lattice, l'output simile a questo:

      diff   lwr   upr  p.adj 
Good-Fair   -0.19695197 -0.23342631 -0.16047764 0.000000e+00 
Very Good-Fair -0.23975525 -0.27344709 -0.20606342 0.000000e+00 
Premium-Fair  -0.15418175 -0.18762721 -0.12073628 0.000000e+00 
Ideal-Fair  -0.34329965 -0.37610961 -0.31048970 0.000000e+00 
Very Good-Good -0.04280328 -0.06430194 -0.02130461 5.585171e-07 
Premium-Good  0.04277023 0.02165976 0.06388070 3.256208e-07 
Ideal-Good  -0.14634768 -0.16643613 -0.12625923 0.000000e+00 
Premium-Very Good 0.08557350 0.06974902 0.10139799 0.000000e+00 
Ideal-Very Good -0.10354440 -0.11797729 -0.08911151 0.000000e+00 
Ideal-Premium  -0.18911791 -0.20296592 -0.17526989 0.000000e+00 

E 'possibile avere tutte le p-value < 0,05 per avere uno sfondo di colore grigio automaticamente o evidenziato in qualche modo? Ovviamente, per questo set sarebbe l'intera colonna, ma spero in qualcosa che funzioni con tutti i miei dati.

risposta

17

Ciao provare questo:

\documentclass{article} 
\usepackage{color} 
\begin{document} 

<<echo=FALSE, results='asis'>>= 
df = data.frame(V1 = LETTERS[1:6], V2 = runif(6, 0, 1)) 
df$V3 = ifelse(df$V2 < 0.5, paste0("\\colorbox{red}{", df$V2, "}"), df$V2) 
library(xtable) 
print(xtable(df), sanitize.text.function = function(x) x) 
@ 

\end{document} 

EDIT

Se si dispone di più le condizioni, una soluzione è quella di usare il pacchetto dplyr e la funzione case_when:

set.seed(123) 
df <- data.frame(V1 = LETTERS[1:6], V2 = runif(6, 0, 1)) 

library("dplyr") 
df %>% 
    mutate(
    V3 = case_when(
     V2 < 0.5 ~ paste0("\\colorbox{red}{", round(V2, 3), "}"), 
     V2 >= 0.5 & V2 < 0.8 ~ paste0("\\colorbox{blue}{", round(V2, 3), "}"), 
     TRUE ~ formatC(V2, digits = 3) 
    ) 
) 
# V1  V2      V3 
# 1 A 0.2875775 \\colorbox{red}{0.288} 
# 2 B 0.7883051 \\colorbox{blue}{0.788} 
# 3 C 0.4089769 \\colorbox{red}{0.409} 
# 4 D 0.8830174     0.883 
# 5 E 0.9404673     0.94 
# 6 F 0.0455565 \\colorbox{red}{0.046} 
+0

grazie @Victorp, ma ho notato che il numero di cifre decimali è molto più lungo sui dati trasformati. Qualche suggerimento su come tenerlo allo stesso numero di cifre delle altre colonne? – PaoloCrosetto

+0

@Victorp 'df $ V2 <0.5';) –

+0

@PaoloCrosetto, è possibile eseguire' round (df $ V2, 4L) 'all'interno di' ifelse'. Inoltre puoi aggiungere 'opzioni (scipen = 10)' per penalizzare la notazione scientifica. – akhmed

1

Victorp fornire un eccellente soluzione e mi ha dato un tale sollievo dopo una lunga lotta. Poi più tardi ho bisogno di imporre più di una condizione sullo stesso set di dati, il che significa che ho bisogno di due colori diversi sulle celle in base a condizioni diverse, per risolvere questo, totalmente basato sulla risposta di Victorp, ho trovato una soluzione e spero che questo possa aiutare quelli ne ho bisogno in futuro.

<<echo=FALSE, results='asis'>>= 
    df = data.frame(V1 = LETTERS[1:6], V2 = runif(6, 0, 1),V3 = runif(6, 0, 1)) 
    ## replicate the data frame of which you are going to highlight the cells 
    ## the number of duplicates should be equal to number of conditions you want to impose 
    temp.1<-df 
    temp.2<-df 
    ## impose conditions on those temporary data frame separately. 
    ## change the columns you want to 
    for (i in colnames(temp.1)[2:3]) { 
    temp.1[,i]= ifelse(temp.1[,i] <= 0.5, 
           paste0("\\colorbox{red}{", temp.1[,i], "}"), temp.1[,i])} 
    rm(i) 


    for (i in colnames(temp.2)[2]) { 
    temp.2[,i]= ifelse(temp.2[,i] > 0.5 & temp.2[,i] <=0.8, 
           paste0("\\colorbox{blue}{", temp.2[,i], "}"),temp.2[,i])} 
    rm(i) 
    ## then record the position of cells under you conditions 
    pos.1<-which(df[,] <=0.5,arr.ind = TRUE) 
    pos.2<-which(df[,] >0.5 & df[,]<=0.8,arr.ind = TRUE) 
    ## replace cells in original data frame that you want to highlight 
    ## replace those values in temp which satisfy the condition imposed on temp.1 
    if(length(pos.1)>0) { 
     temp[pos.1]<-temp.1[pos.1] 
    } 


    ## replace those values in temp which satisfy the condition imposed on temp.2 
    if(length(pos.2)>0) { 
     temp[pos.2]<-temp.2[pos.2] 
    } 
    rm(temp.1,temp.2,pos.1,pos.2) 
    @ 

allora stampare df nel modo che ti piace. Questo funziona, tuttavia, dato il potere di R, credo che ci dovrebbero essere modi molto più facili per questo.

Problemi correlati