【问题标题】:How to apply a function with multiple arguments and create a dataframe?如何应用具有多个参数的函数并创建数据框?
【发布时间】:2020-11-26 05:10:17
【问题描述】:

我有一个函数接受两个参数fre(data, var)。我想将此函数应用于一些选定的变量,并通过按行绑定它们来创建数据框。我已经通过这段代码完成了很长的路要走。

功能

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
}

读取示例数据:

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

使用选择变量名运行函数:

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

通过绑定行创建数据集:

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

结果:

我正在寻找一种方法来简化此代码。我试过使用 lapply 但我得到了不同的错误。例如,当我尝试运行 lapply(list_var, fre) 时,我收到此错误:Error in is_string(x) : argument "var" is missing, with no default。我知道我需要将多个参数传递给 lapply,但我不确定如何使用我创建的函数来做到这一点。另外,我正在寻找除了使用lapply 之外的其他方法来快速创建数据框。

【问题讨论】:

    标签: r


    【解决方案1】:

    更改您的函数以接受字符串参数:

    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
    }
    

    然后使用lapply将列名作为字符串传递给fre函数。

    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%
    

    【讨论】:

      猜你喜欢
      • 2017-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-25
      • 1970-01-01
      • 1970-01-01
      • 2021-12-14
      相关资源
      最近更新 更多