How tabulate with n and % in diferents columns

Hello, do you have any idea how to make that in the final tables there is a column for the n and another for the %?

For example, with this reprex:

# A tibble: 5 x 2
  var1  var2 
  <chr> <chr>
1 A     A    
2 B     B    
3 A     A    
4 B     B    
5 A     B

I use gtsummary and createtableone and in both packages the information is always in the same column separated by a space like this:

df %>%
CreateTableOne(data=.,
                 vars = c("var1", "var2")) %>%
  print(showAllLevels = T)

Output:

level Overall  
  n              5        
  var1 (%) A     3 (60.0) 
           B     2 (40.0) 
  var2 (%) A     2 (40.0) 
           B     3 (60.0)

Or:

df %>%
tbl_summary()

Output:

image

and I would like to know how to make them in 2 different columns like this:

n %
var1
A 3 60
B 2 40
var2 A 2 40
B 3 60

How do i get this table? I export the table I get with Createtableone and I modiify it on excel so i can have the n and % in 2 columns, but I lost a lot of time doing it.

I think we need a FAQ: How to do a minimal reproducible example ( reprex ) for beginners

A handy way to supply some sample data is the dput() function. In the case of a large dataset something like dput(head(mydata, 100)) should supply the data we need.

Hi, I edited my post incluiding a reprex

Well it is not exactly a reprex but it helps.

First, while gtsummary is an R package, createtableone is a function in the tableone package.

In any case, both are explicitly intended to give that output which seems to be Table One in a research article in a medical journal. I don't think either are intended to do what you want.

Here is something that will give you the two tables you want, that is the calculated tables. If you need them in the format in your example above we will have to fuss around with one of the table packages.

dat1  <- structure(list(var2 = c("A", "B", "A", "B", "B"), var1 = c("A", 
        "B", "A", "B", "A")), class = "data.frame", row.names = c(NA, 
        -5L))

tv1  <- table(dat1$var1)
tv2  <- table(dat1$var2)
nn  <- nrow(dat1)

vt1  <- as.data.frame(tv1)
vt1$percent  <-  (vt1$Freq/nn) * 100 

vt2  <- as.data.frame(tv2)
vt2$percent  <-  (vt2$Freq/nn) * 100 

vt1
vt2

Isn’t a more general way? Because if I want complicated tables this way doesn’t work (like p value, % by row instead of columns or stratified tables).

It depends on the structure of the data and the desired layout. There are complete packages, for say, formatting the output of regression models. Also it may be simpler to handle more complex data.frames . The data you supplied was so simple that I decided the only way to do the job was brute force. There likely is a better may but I did not see it.

Things like p values or % by row instead of columns or stratified tables are quite possible if I understand the question. Without sample data for the types of tables you may need, it's impossible to say much more.


library(gt)
library(tidyverse)

dat1 <- structure(list(var2 = c("A", "B", "A", "B", "B"), var1 = c(
  "A",
  "B", "A", "B", "A"
)), class = "data.frame", row.names = c(
  NA,
  -5L
))

dat_prep <- map_dfr(
  sort(names(dat1)),
  ~ dat1 |>
    count(!!sym(.x)) |>
    mutate(`%` = scales::percent(n / sum(n))) |>
    pivot_longer(
      cols = .x, names_to = "grp",
      values_to = "nm"
    )
) |> relocate(nm, grp)

dat_prep |> gt(
   rowname_col = "nm",
  groupname_col = "grp"
)  |> cols_width(1 ~px(60))

image

1 Like

This topic was automatically closed 42 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.