Reputation: 798
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:
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.
Upvotes: 0
Views: 151
Reputation: 388817
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%
Upvotes: 1