HSC
HSC

Reputation: 129

R need a help to correct a function

library(tidyverse)
#make a sample data frame
a <- c(2000,2000,2000,2000,2001,2001,2001,2001)
b <- c("M","M","M","F","F","M","F","F")
d<- c("Yes","No","Yes","No","No","Unknown","Unknown","Yes")
e <- c("Unknown","No","No","Yes","Unknown","Yes","No","Unknown")
df <- data.frame(a,b,d,e)
colnames(df) <- c("Year","Gender","q1","q2")

# make a table for q1
myvar <- c("Gender","q1")
mydf <- df[,myvar]
table1 <- mydf %>%
  pivot_longer(-q1) %>%
  group_by(name,q1,value) %>%
  summarise(n=n()) %>%
  mutate(prop = round(n/sum(n),3)*100,
         summary_str = glue::glue("{n}({prop}%)")) %>%
  pivot_wider(id_cols = c(name,value), names_from = "q1", values_from = "summary_str")

#make the function creating a table 
maketable <- function(df,x){
  myvar <- c("gender",paste0(x))
  mydf <- df[,myvar]
  table1 <- mydf %>%
    pivot_longer(-get(x)) %>%
    group_by(name,get(x),value) %>%
    summarise(n=n()) %>%
    mutate(prop = round(n/sum(n),3)*100,
           summary_str = glue::glue("{n}({prop}%)")) %>%
    pivot_wider(id_cols = c(name,value), names_from = paste0(x), values_from = "summary_str")
   colnames(table1)
}
maketable(df,q1)
maketable(df,q2)

Error in paste0(x): object 'q1' not found.

I want to make a function, so that I can use it for q2.

Could anyone help to correct the code? or suggest a better way? Output per variable is as below enter image description here

Upvotes: 0

Views: 67

Answers (3)

Triss
Triss

Reputation: 581

I have tried this one here

my_func = function(x)
{

new_df = df %>% group_by(Gender) %>% count({{x}}) %>% pivot_wider(names_from = {{x}}, values_from = n)

return(new_df)
}

Upvotes: 1

MrFlick
MrFlick

Reputation: 206382

If you want to pass in unquoted column names to your function, you can use the {{}} (embrace) operator to inject them into your commands. For example

maketable <- function(df,x){
  df %>%
    select(Gender, {{x}}) %>% 
    pivot_longer(-{{x}}) %>% 
    group_by(name,{{x}},value)%>%
    summarise(n=n()) %>% 
    mutate(prop = round(n/sum(n),3)*100,
           summary_str = glue::glue("{n}({prop}%)")) %>% 
    pivot_wider(id_cols = c(name,value), names_from = {{x}}, values_from = "summary_str")
}
table1 <-maketable(df, q1)

See the programming with dplyr guide for more information.

Also note that the function just returns the new value. If you want to assign that to a new variable, make sure you do that outside the function. Values created inside of functions will not appear outside.

Upvotes: 2

Kra.P
Kra.P

Reputation: 15133

I'm not sure that this is what you asked

    colns <- colnames(df)

    lapply(colns[c(3:4)], function(x) {
      myvar <- c("Gender", x)
      mydf <- df[,myvar]
      table1 <- mydf%>%
        pivot_longer(-x) %>%
        group_by_all %>%
        summarise(n=n()) %>%
        mutate(prop = round(n/sum(n),3)*100,
               summary_str = glue::glue("{n}({prop}%)")) %>%
        pivot_wider(id_cols = c(name,value), names_from = x, values_from =         "summary_str")
      
    })

result is like

    [[1]]
    # A tibble: 2 x 5
    # Groups:   name [1]
      name   value No       Unknown  Yes     
      <chr>  <chr> <glue>   <glue>   <glue>  
    1 Gender F     2(25%)   1(12.5%) 1(12.5%)
    2 Gender M     1(12.5%) 1(12.5%) 2(25%)  
    
    [[2]]
    # A tibble: 2 x 5
    # Groups:   name [1]
      name   value No       Unknown  Yes     
      <chr>  <chr> <glue>   <glue>   <glue>  
    1 Gender F     1(12.5%) 2(25%)   1(12.5%)
    2 Gender M     2(25%)   1(12.5%) 1(12.5%)

You may need to change

    lapply(colns[c(3:4)],...

3:4 to 3:102 for q1~q100

Upvotes: 0

Related Questions