R basics: working with multiple variables at once and their output

Viewed 54

I have a survey dataset with 40 ordered factor variables. The variables are transformed into characters when the data is imported.Please correct me if I am wrong, as I am thinking of using the apply function here.

Below my data manipulation:

### data    
v1 <- as.character(c(1,4,2,4,3,1,3,4,5,2,2,3,6,5,4,6,5,4,5,6,6,2,4,3,4,5,6,1,6,3,5,6,3,2,4,5,3,2,4,5,3,2,4))
v2 <- as.character(c(3,4,1,4,5,1,3,1,5,6,4,3,4,5,6,3,3,5,4,3,3,5,6,3,4,3,4,6,3,1,1,3,4,5,6,1,3,6,4,3,1,6,5))

df <- data.frame(v1,v2)

### transform into ordered factor

df$v1.f <- as.factor(df$v1)
df$v1.f <- ordered(df$v1.f, levels = c("1", "2", "3", "4", "5", "6"))

The real levels are unsorted characters, which is why I included the step. I don't mind typing this for all variables, but it seems redundant.

My second issue is with the output. I would like to create a fancy report and know how to generate the numbers for it:

v1.freq <- table(df$v1.f)
v1.perc <- round(prop.table(v1.freq),2)*100
v1.med <- median(df$v1)

How can a table that contains all the information for all the variables at once for multiple variables be printed - especially when there are no answers to a level (see v2, where there is no response for level 2; table() simply skips over the level).

How do I turn the R output in a table that has the levels as headers and frequencies and percentages as rows for multiple variables?

Copy/pasting the numbers into an Excel Sheet seems - again - unnecessary and prone to errors.

1 Answers

First, you might want to check if you have a stringAsFactor option for your data import function.

Then, as I understand, you want to transform your variable into ordered factors, and this for all of them. You can wrap this into a dplyr sentence, and use forcats to handle factors. Let's take your data:

library(tidyverse)
df %>% 
  mutate(across(1:2, ~factor(.))) %>% 
  mutate(across(1:2,~ordered(.))) %>% 
  str()

Output:

'data.frame':   43 obs. of  2 variables:
 $ v1: Ord.factor w/ 6 levels "1"<"2"<"3"<"4"<..: 1 4 2 4 3 1 3 4 5 2 ...
 $ v2: Ord.factor w/ 5 levels "1"<"3"<"4"<"5"<..: 2 3 1 3 4 1 2 1 4 5 ...

As you can see, the variables are transformed as ordered factors, with levels ordered alphabetically. To explain, mutate is to alterate your variables, across specify which variables you want to change, and how. Here, we want to mutate the variable 1 to 2 and apply to them the functions factor and then ordered. If the alphabetical levelling isn't the one desired, you can still mutate the column by it self and give the levels argument.

For the second question, as far as there is no level "2" for V2, unlike V1, you cannot merge the two variable, unless you add a level for V2 with NA. You can still check janitor::tabyl to give you cross frequencies, and create one table per variable:

library(janitor)
df2 <- df %>% 
  mutate(across(1:2, ~factor(.))) %>% 
  mutate(across(1:2,~ordered(.)))

map(df2, tabyl)

Output:

$v1
 .x[[i]]  n    percent
       1  3 0.06976744
       2  7 0.16279070
       3  8 0.18604651
       4 10 0.23255814
       5  8 0.18604651
       6  7 0.16279070

$v2
 .x[[i]]  n   percent
       1  7 0.1627907
       3 13 0.3023256
       4  9 0.2093023
       5  7 0.1627907
       6  7 0.1627907
Related