0

I have a function that takes in two arguments fre(data, var). I would like to apply this function to a few selected variables and create a dataframe by binding them by rows. I've done it the long way through this code.

Function:

fre <- function(.data, var) {
  var <- rlang::ensym(var)
  abc <- questionr::na.rm(.data[, rlang::as_string(var)])
  abc <- questionr::freq(abc)
  abc <- cbind(Label = rownames(abc), abc)
  abc <- questionr::rename.variable(abc, "n", "Frequency")
  abc <- questionr::rename.variable(abc, "%", "Percent")
  abc <- tidyr::separate(abc, Label, into = c("Value", "Label"), sep = "] ")
  row.names(abc) <- NULL
  abc <- abc %>% dplyr::mutate(Value = gsub("\\[|\\]", "", Value)) %>% 
    dplyr::select(Label, Value, Frequency, Percent) %>% 
    select(Label, Percent) 
  abc$Percent <- paste0(round(abc$Percent), "%")
  abc <- abc %>% 
    tidyr::pivot_wider(names_from = Label, values_from = Percent) 
  Label <- var_label(.data[[var]])
  Name <- deparse(substitute(var))
  abc <- cbind(Name, Label, abc)
  abc
}

Read example data:

dat <- haven::read_spss("http://staff.bath.ac.uk/pssiw/stats2/SAQ.sav")

Run function with select variable names:

r3 <- fre(dat, Q03)
r6 <- fre(dat, Q06)
r7 <- fre(dat, Q07)
r8 <- fre(dat, Q08)
r10 <- fre(dat, Q10)

Create dataset by binding rows:

rbind(r3, r6, r7, r8, r10)

Result:

enter image description here

I'm looking for a way to simplify this code. I've tried using lapply but I'm getting different errors. For instance, when I try running lapply(list_var, fre), I get this error: Error in is_string(x) : argument "var" is missing, with no default. I know I need to pass multiple arguments to lapply, but I'm not sure how to do that with the function I created. Also, I'm looking for other ways apart from using lapply to quickly create a dataframe.

1 Answer 1

1

Change your function to accept string arguments :

fre <- function(.data, var) {
  abc <- questionr::na.rm(.data[, var])
  abc <- questionr::freq(abc)
  abc <- cbind(Label = rownames(abc), abc)
  abc <- questionr::rename.variable(abc, "n", "Frequency")
  abc <- questionr::rename.variable(abc, "%", "Percent")
  abc <- tidyr::separate(abc, Label, into = c("Value", "Label"), sep = "] ")
  row.names(abc) <- NULL
  abc <- abc %>% dplyr::mutate(Value = gsub("\\[|\\]", "", Value)) %>% 
    dplyr::select(Label, Value, Frequency, Percent) %>% 
    select(Label, Percent) 
  abc$Percent <- paste0(round(abc$Percent), "%")
  abc <- abc %>% 
    tidyr::pivot_wider(names_from = Label, values_from = Percent) 
  Label <- var_label(.data[[var]])
  Name <- var
  abc <- cbind(Name, Label, abc)
  abc
}

Then pass column names to fre function as string using lapply.

cols <- c('Q03', 'Q06', 'Q07', 'Q08', 'Q10')
result <- do.call(rbind, lapply(cols, fre, .data = dat))
#Or a bit shorter
#result <- purrr::map_df(cols, fre, .data = dat))
result

#  Name                                       Label Strongly agree Agree Neither Disagree
#1  Q03               Standard deviations excite me            19%   26%     34%      17%
#2  Q06       I have little experience of computers            27%   44%     13%      10%
#3  Q07                       All computers hate me             7%   34%     26%      24%
#4  Q08       I have never been good at mathematics            15%   58%     19%       6%
#5  Q10 Computers are useful only for playing games            14%   57%     18%      10%
#  Strongly disagree
#1                3%
#2                6%
#3                8%
#4                3%
#5                2%
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.