Counts & Prozentangaben in XTABLE, Sweave, R, Kreuztabellierungen
Frage
Edit: Gebäude aus unterhalb der aL3xa Antwort, ich habe seine Syntax unten geändert. Nicht perfekt, aber immer näher. Ich habe immer noch nicht gefunden, einen Weg zu machen \ mehrspaltigen XTABLE akzeptieren {} Argumente für Spalten oder Zeilen. Es scheint auch, dass Hmisc einige dieser Art von Aufgaben hinter den Kulissen behandelt, aber es sieht aus wie ein Stück eines Unternehmens zu verstehen, was da los ist. Hat jemand Erfahrung mit der Latex-Funktion in Hmisc?
ctab <- function(tab, dec = 2, margin = NULL) {
tab <- as.table(tab)
ptab <- paste(round(prop.table(tab, margin = margin) * 100, dec), "%", sep = "")
res <- matrix(NA, nrow = nrow(tab) , ncol = ncol(tab) * 2, byrow = TRUE)
oddc <- 1:ncol(tab) %% 2 == 1
evenc <- 1:ncol(tab) %% 2 == 0
res[,oddc ] <- tab
res[,evenc ] <- ptab
res <- as.table(res)
colnames(res) <- rep(colnames(tab), each = 2)
rownames(res) <- rownames(tab)
return(res)
}
Ich möchte eine Tabelle erstellen, für LaTeX-Ausgabe formatiert, die beide enthält die Zählungen und Prozentsätze für jede Spalte oder Variable. Ich habe nicht eine fertige Lösung für dieses Problem gefunden, aber das Gefühl, ich muss das Rad zu einem gewissen Grad werden neu erstellt.
Ich habe eine Lösung für gerade Tabellierungen entwickelt, aber ich kämpfe mit etwas für eine Kreuztabellierung nehmen.
Zunächst einige Beispieldaten:
#Generate sample data
dow <- sample(1:7, 100, replace=TRUE)
purp <- sample(1:4, 100, replace=TRUE)
dow <- factor(dow, 1:7, c("Mon", "Tues", "Wed", "Thurs", "Fri", "Sat", "Sun"))
purp <- factor(purp, 1:4, c("Business", "Commute", "Vacation", "Other"))
Und nun die Arbeits gerade Tab-Funktion:
customTable <- function(var, capt = NULL){
counts <- table(var)
percs <- 100 * prop.table(counts)
print(
xtable(
cbind(
Count = counts
, Percent = percs
)
, caption = capt
, digits = c(0,0,2)
)
, caption.placement="top"
)
}
#Usage
customTable(dow, capt="Day of Week")
customTable(purp, capt="Trip Pupose")
hat jemand irgendwelche Vorschläge für das für Kreuztabellierungen Annahme (d Tag der Woche Reisezweck)? Hier ist, was ich gerade geschrieben habe, was nicht die XTABLE Bibliothek nicht verwendet und FAST funktioniert, aber ist nicht dynamisch und ist ziemlich hässlich Arbeit mit:
#Create table and percentages
a <- table(dow, purp)
b <- round(prop.table(a, 1),2)
#Column bind all of the counts & percentages together, this SHOULD become dynamic in future
d <- cbind( cbind(Count = a[,1],Percent = b[,1])
, cbind(Count = a[,2], Percent = b[,2])
, cbind(Count = a[,3], Percent = b[,3])
, cbind(Count = a[,4], Percent = b[,4])
)
#Ugly function that needs help, or scrapped for something else
crossTab <- function(title){
cat("\\begin{table}[ht]\n")
cat("\\begin{center}\n")
cat("\\caption{", title, "}\n", sep="")
cat("\\begin{tabular}{rllllllll}\n")
cat("\\hline\n")
cat("", cat("", paste("&\\multicolumn{2}{c}{",colnames(a), "}"), sep = ""), "\\\\\n", sep="")
c("&", cat("", colnames(d), "\\\\\n", sep=" & "))
cat("\\hline\n")
c("&", write.table(d, sep = " & ", eol="\\\\\n", quote=FALSE, col.names=FALSE))
cat("\\hline\n")
cat("\\end{tabular}\n")
cat("\\end{center}\n")
cat("\\end{table}\n")
}
crossTab(title = "Day of week BY Trip Purpose")
Lösung 3
war ich nicht in der Lage, herauszufinden, wie ein Mehrspaltenkopf mit XTABLE zu erzeugen, aber ich wusste, dass ich für den Druck meiner zählt und Prozentsätze in der gleichen Spalte verketten kann. Nicht ideal, aber scheint die Aufgabe zu erledigen. Hier ist die Funktion, die ich geschrieben habe:
ctab3 <- function(row, col, margin = 1, dec = 2, percs = FALSE, total = FALSE, tex = FALSE, caption = NULL){
tab <- as.table(table(row,col))
ptab <- signif(prop.table(tab, margin = margin), dec)
if (percs){
z <- matrix(NA, nrow = nrow(tab), ncol = ncol(tab), byrow = TRUE)
for (i in 1:ncol(tab)) z[,i] <- paste(tab[,i], ptab[,i], sep = " ")
rownames(z) <- rownames(tab)
colnames(z) <- colnames(tab)
if (margin == 1 & total){
rowTot <- paste(apply(tab, 1, sum), apply(ptab, 1, sum), sep = " ")
z <- cbind(z, Total = rowTot)
} else if (margin == 2 & total) {
colTot <- paste(apply(tab, 2, sum), apply(ptab, 2, sum), sep = " ")
z <- rbind(z,Total = colTot)
}
} else {
z <- table(row, col)
}
ifelse(tex, return(xtable(z, caption)), return(z))
}
Wahrscheinlich nicht das Endprodukt, sondern hat eine gewisse Flexibilität in den Parametern zu ermöglichen. Auf der untersten Ebene ist nur ein Wrapper von table()
, sondern kann auch generieren als auch LaTeX formatierte Ausgabe. Hier ist, was ich in einem Sweave
Dokument am Ende mit:
<<echo = FALSE>>=
for (i in 1:ncol(df)){
print(ctab3(
col = df[,1]
, row = df[,i]
, margin = 2
, total = TRUE
, tex = TRUE
, caption = paste("Dow by", colnames(df[i]), sep = " ")
))
}
@
Andere Tipps
In dem Tabellen-Paket ist eine Zeile:
# data:
dow <- sample(1:7, 100, replace=TRUE)
purp <- sample(1:4, 100, replace=TRUE)
dow <- factor(dow, 1:7, c("Mon", "Tues", "Wed", "Thurs", "Fri", "Sat", "Sun"))
purp <- factor(purp, 1:4, c("Business", "Commute", "Vacation", "Other"))
dataframe <- data.frame( dow, purp)
# The packages
library(tables)
library(Hmisc)
# The table
tabular( (Weekday=dow) ~ (Purpose=purp)*(Percent("row")+ 1) ,data=dataframe )
# The latex table
latex( tabular( (Weekday=dow) ~ (Purpose=purp)*(Percent("col")+ 1) ,data=dataframe ))
Mit booktabs, können Sie dies erhalten (kann weiter angepasst werden):
Gute Frage, dieses irgendjemandes mich für eine Weile stört (es ist nicht , die hart, es ist nur mir höllisch faul ... wie üblich). Allerdings ... obwohl die große Frage, Ihr Ansatz, fürchte ich, ist es nicht. Es ist unbezahlbar Paket namens xtable
, dass man (mis) Verwendung. Außerdem ist dieses Thema zu häufig - gibt es eine große Chance, dass es bereits einige fertige Lösung sitzt irgendwo auf die Internete .
Einer dieser Tage über bin ich es zu arbeiten, ein für alle Mal (Ich werde den Code auf GitHub Post). Die Hauptidee geht ein wenig wie diese: Möchten Sie Frequenz und / oder Prozentwerte innerhalb einer Zelle (getrennt durch \) oder Reihen mit absoluten und relativen Frequenzen (oder%) in Aufeinanderfolge? Ich würde gehen mit dem 2 nd ein, so dass ich jetzt einer "Erste-Hilfe" Lösung veröffentlichen werden:
ctab <- function(tab, dec = 2, ...) {
tab <- as.table(tab)
ptab <- paste(round(prop.table(tab) * 100, dec), "%", sep = "")
res <- matrix(NA, nrow = nrow(tab) * 2, ncol = ncol(tab), byrow = TRUE)
oddr <- 1:nrow(tab) %% 2 == 1
evenr <- 1:nrow(tab) %% 2 == 0
res[oddr, ] <- tab
res[evenr, ] <- ptab
res <- as.table(res)
colnames(res) <- colnames(tab)
rownames(res) <- rep(rownames(tab), each = 2)
return(res)
}
Jetzt versuchen so etwas wie:
data(HairEyeColor) # load an appropriate dataset
tb <- HairEyeColor[, , 1] # choose only male respondents
ctab(tb)
Brown Blue Hazel Green
Black 32 11 10 3
Black 11.47% 3.94% 3.58% 1.08%
Brown 53 50 25 15
Brown 19% 17.92% 8.96% 5.38%
Red 10 10 7 7
Red 3.58% 3.58% 2.51% 2.51%
Blond 3 30 5 8
Blond 1.08% 10.75% 1.79% 2.87%
Stellen Sie sicher, beladen Sie xtable
Paket und Verwendung print
(es ist eine generische Funktion, so dass Sie ein xtable
eingestuft Objekt übergeben muss). Es ist wichtig, dass Sie die Zeilennamen unterdrücken. Ich werde diese ein morgen optimieren - es sollte sein xtable
kompatibel. Es ist 03.00 Uhr in meiner Zeitzone, also mit diesen Zeilen werde ich meine Antwort beenden:
print(xtable(ctab(tb)), include.rownames = FALSE)
Cheers!
Mit multicolumn
mit latex
aus dem Hmisc Paket ist nicht so schlecht. Dieses minimale Sweave Dokument:
\documentclass{article}
\begin{document}
<<echo = FALSE,results = tex>>=
library(Hmisc)
dow <- sample(1:7, 100, replace=TRUE)
purp <- sample(1:4, 100, replace=TRUE)
dow <- factor(dow, 1:7, c("Mon", "Tues", "Wed", "Thurs", "Fri", "Sat", "Sun"))
purp <- factor(purp, 1:4, c("Business", "Commute", "Vacation", "Other"))
tbl <- table(dow,purp)
tbl_prop <- round(100 * prop.table(tbl,1),2)
tbl_df <- as.data.frame.matrix(tbl)
tbl_prop_df <- as.data.frame.matrix(tbl_prop)
colnames(tbl_prop_df) <- paste(colnames(tbl_prop_df),"1",sep = "")
df <- cbind(tbl_df,tbl_prop_df)[,ggplot2:::interleave(1:4,5:8)]
colnames(df) <- rep(c('n','\\%'),times = 4)
latex(object=df,file="",cgroup = colnames(tbl_df),
colheads = NULL,rowlabel = "",
center = "centering",collabel.just = rep("r",8))
@
\end{document}
Erzeugt das für mich:
Natürlich, ich habe hart codiert ein gutes Stück von Sachen, und es könnte schlankeres Möglichkeiten, den Datenrahmen zu erzeugen, dass Sie zu latex
vorbei am Ende, aber dies sollte zumindest einen Anfang mit multicolum
geben.
Auch eine leichte Gotcha, die ich verwendet habe ggplot2 's interleave
Funktion, wenn die Zählungen und Prozentsätze kombiniert die Spalten zu wechseln. Das ist nur, weil ich faul bin.
Wie würde diese Arbeit für Sie?
library(reshape)
library(plyr)
df <- data.frame(dow = dow, purp = purp)
df.count <- count(df)
df.count <- ddply(df.count, .(dow), transform, p = round(freq / sum(freq),2))
df.m <- melt(df.count)
df.print <- cast(df.m, dow ~ purp + variable)
library(xtable)
xtable(df.print)
Es gibt Ihnen nicht schön multicolumns, und ich habe nicht genug Erfahrung mit xtable
um herauszufinden, ob das möglich ist. Wenn Sie jedoch, Sie gehen benutzerdefinierte Funktionen zu schreiben, könnten Sie versucht werden, die über die Spaltennamen von df.print
arbeitet. Man könnte sogar in der Lage sein, eine so allgemein zu schreiben alle möglichen Neufassung Datenrahmen als Eingabe zu übernehmen.
Edit:
Ich dachte, eine gute Lösung für Sie näher. Nach dem Erstellen df.m
df.preprint <- ddply(df.m, .(dow, purp), function(x){
x <- cast(x, dow ~ variable)
x$value <- paste(x$freq, x$p, sep = " / ")
return(c(value = x$value))
}
)
df.print <- cast(df.preprint, dow ~ purp)
print(xtable(df.print), include.rownames = F)
Nun wird jede Zelle N / percent
Werte enthalten
Ich weiß, dieser Thread ist ein bisschen alt, aber die tableNominal () Funktion in dem reporttools Paket kann die Funktionalität die Sie suchen.
tab<-table(row, col)
ctab<-round(100*prop.table(tab,2), 2) # for column percents (see the args for prop.table)
for (i in 1:length(tab)) {
ctab[i]<-paste(tab[i]," (", ctab[i], "%", ")", sep="")
}
require(xtable);
k<-xtable(ctab,digits=1) # make latex table