首页 > 解决方案 > 在多变量函数中解析变量时出错

问题描述

在为两个变量创建摘要时,我在 var <- parse_expr(var) 上遇到错误,任何人对此都有任何线索...??

dataa<-data.frame(
  aa = c("q","r","y","v","g","y","d","s","n","k","y","d","s","t","n","u","l","h","x","c","q","r","y","v","g","y","d","s","n","k","y","d","s","t","n","u","l","h","x","c"),
  col1=c(1,2,3,2,1,2,3,4,4,4,5,3,4,2,1,2,5,3,2,1,2,4,2,1,3,2,1,2,3,1,2,2,4,4,4,1,2,5,3,5),
  col2=c(250,1100,100,750,400,100,200,700,500,700,200,600,200,200,600,300,400,300,200,500,700,500,600,400,400,600,500,600,400,100,700,300,200,700,700,200,300,700,200,400),
  col3= c(2150,3213,2580,4335,2228,3795,2319,2363,2252,3015,2978,2127,3938,3013,3063,4202,4340,4247,3755,4145,3300,3739,3294,2944,4152,2898,2500,3164,2384,2824,3431,2864,3752,2265,3332,3321,3418,3521,2689,2186)
)    




错误:错误:x 必须是字符向量或 R 连接

标签: r

解决方案


您的代码有一些问题。部分问题可能是您的代码难以调试,因为您的间距和缩进使得很难看到发生了什么。这不是风格或品味的次要问题;老实说,它对编写和维护代码的容易程度产生了影响。

实际上导致错误的问题是您的第一个函数调用rlang::parse_expr(var),但var不是字符串 - 它实际上是您数据中的一整列。当您调用 时tab_1d(tab,tab[i],var_name_list[i],Suff),您正在传递tab[i],这是数据框中的一整列。你可能打算通过var_list[i]

另一个大问题是您的函数包含的参数。您的第一个函数包含两个实际未在函数内部使用的参数:Name_of_variableSuff. 更糟糕的是,当您调用 时 tab_1d(tab,tab[i],var_name_list[i],Suff),您将Suff作为未命名变量传递,tab_1d因此认为您将字符串传递Suffdecimal,因此无法正确解释它。

用 R 之类的函数式语言编写代码以识别代码中的重复模式并查看是否可以创建一个防止代码重复的函数时,这是一个好主意。这使得更容易看到正在发生的事情。例如,您可以通过首先定义一个允许您更轻松地指定格式的小格式化函数来简化您的第一个函数:

format_quantile <- function(x, quantile, numdig) 
{
  quantile(x, type = 6, probs = quantile, na.rm = TRUE) %>%
    round(numdig) %>%
    format(nsmall = numdig)
}

现在你的 main 函数看起来像这样:

tab_1d <- function(dataset, var, numdig) {
  var <- rlang::parse_expr(var)
  dataset %>% 
    filter(!is.na(!!var)) %>%   
    summarise(q25     = format_quantile(!!var, quantile = 0.25, numdig = numdig), 
              Median  = format_quantile(!!var, quantile = 0.5, numdig = numdig),
              Average = format(round(mean(!!var, na.rm = TRUE), digits = numdig)),
              q75     = format_quantile(!!var, quantile = 0.75, numdig = numdig),
    N = sum(!is.na(!!var)))
}

您还可以使用以下方法简化使用循环创建列表的函数lapply

tab_value_1d_row <- function(data, var_list, decimal) 
{
  tab <- as.data.frame(data[var_list])
  table_list <- lapply(var_list, function(i) tab_1d(tab, i, +decimal))
  Reduce(rbind, table_list) %>% flextable()
}

所以现在当你这样做时

tab_value_1d_row(data = dataa, var_list = c("col2", "col3"), decimal = TRUE)

你得到:

在此处输入图像描述


推荐阅读