With df:
df <- data.frame(value=abs(rnorm(100, 25, 5)), status=sample(0:1,100,replace=T))
df$value[sample(1:100,5)] <- NA
I need to get a frequency (percentage) table (better return a matrix) like the following:
value | status(0) status(1)
----------------------------
<=25 | 23 (23%) 20 (20%)
>25 | 27 (27%) 25 (25%)
NA | 3 (3%) 2 (2%)
I can do this using:
br <- seq(0, 50, 25)
with(df, summary(cut(value[status==0], br, labels=br[-1],
include.lowest=T, ordered_result=T)))
with(df, summary(cut(value[status==1], br, labels=br[-1],
include.lowest=T, ordered_result=T)))
But would there be a one-time way to return a matrix as above? Thanks!
df$value.cut = cut(df$value, breaks=c(0, 25, 100))
> with(df, table(value.cut, status, useNA='ifany'))
status
value.cut 0 1
(0,25] 26 19
(25,100] 26 24
<NA> 3 2
(Of course this can be combined into 1 line if you want, but I left it as 2 here for better readability.)
EDIT: And if you want a table of proportions, formatted as frequencies, you can do:
df.tab = with(df, table(value.cut, status, useNA='ifany'))
df.tab[,] = paste(df.tab, ' (', 100*prop.table(df.tab), '%)', sep='')
> df.tab
status
value.cut 0 1
(0,25] 26 (26%) 19 (19%)
(25,100] 26 (26%) 24 (24%)
<NA> 3 (3%) 2 (2%)
Another solution using reshape2
.
library(reshape2)
dcast(df, cut(value, breaks = c(0, 25, 100)) ~ status)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With