Использование кавычек в функции R

Я пытаюсь написать функцию R, которая возвращает таблицу сводной статистики (на основе функции get_summary stats из пакета rstatix) и вычисляет критерий Уилкоксона. Это будет выполняться для нескольких переменных Y с интересующей постоянной переменной X (которая будет основой для таблицы сводной статистики).

Вот как функция выглядит сейчас:

summary_stats_and_test <- function(df, xvar, yvars){
  df_res <- df %>% 
    group_by({{ xvar }}) %>% 
    select({{ yvars }}, {{ xvar }}) %>% 
    get_summary_stats(type = "mean_sd") %>% 
    arrange(variable) %>% 
    mutate(across(where(is.numeric), ~ num(., digits = 1)))
  
  stat_test <- yvars %>% 
  paste(" ~ ", xvar) %>% 
  map(as.formula) %>% 
  map_df(~wilcox_test(.x, data = df))
  
  return(list(table = df_res, test = stat_test))
}

Я «обнял» xvar и yvars внутри куска df_res. Однако я не могу понять, как указать значение xvar внутри функции вставки для правильной работы.

Это, например, код:

weight_wc_deltas_vars = c("weight_1", "weight_2", "weight_3", "WC_1", "WC_2", "WC_3")
df %>%  
  mutate(has_weight = if_else(is.na(col_1), "no", "yes")) %>% 
  summary_stats_and_test(xvar = has_weight,
                         yvars=weight_wc_deltas_vars[1:3])

Если has_weight в функции стоит без кавычек, я получаю ошибку: Error: object 'has_weight' not found. Если оно в кавычках, я не получаю ошибки, но функция group_by внутри моей функции не имеет никакого эффекта.

В более общем плане мне не совсем ясно, лучше ли писать аргумент моей функции в кавычках или без них в R. Концепция охвата в контексте tidyverse ясна, но здесь я застрял на та же проблема.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В вашем коде вам необходимо преобразовать имя, на которое указывает xvar, в строку. Вы можете сделать это через

deparse(substitute(xvar), backtick = TRUE)

Обратите внимание на параметр backtick = TRUE! Это важно для правильной обработки несинтаксических имен (например, `foo bar`), передаваемых в функцию.

Но ваш код также неправильно обрабатывает такие имена при передаче через yvars, и вам нужно это исправить. Один из способов — преобразовать yvars в имена (с помощью map(yvars, rlang::sym) или lapply(yvars, as.name)), а затем обратно в строки, как указано выше. Но то, что вы сейчас делаете, в любом случае является обходным путем. Гораздо проще создавать формулы напрямую, а не обходным путем построения строк. Таким образом, вам также не придется преобразовывать xvar в строку.

  stat_test <- yvars %>%
    map(rlang::sym) %>%
    map(\(y) rlang::inject(!! y ~ !! rlang::ensym(xvar))) %>%
    map_df(~ wilcox_test(.x, data = df))

Спасибо! Не могли бы вы подробнее рассказать, почему вы используете оба !! а функции rlang в третьей строке?

user23485480 01.03.2024 17:13

@user23485480 В основном это объясняется на этой странице: rlang.r-lib.org/reference/topic-defuse.htmlrlang::ensym() обезвреживает параметр, чтобы он не оценивался впоследствии. !! интерполирует эту обезвреженную переменную в выражение через rlang::expr(). Если вы используете только !!, !! попытается вычислить xvar, но это не удастся («объект «foo» не найден», если вы вызвали свою функцию с помощью xvar = foo). Если вы используете только rlang::ensym(), rlang::expr() вообще не будет оценивать подвыражение, и в итоге вы получите формулу y ~ lang::ensym(xvar).

Konrad Rudolph 01.03.2024 20:09

Привет, просто чтобы продолжить эту тему, я попробовал функцию, как вы предложили, и получил следующую ошибку: Ошибка в map(): ℹ В индексе: 1. Вызвано ошибкой в ​​x$terms %||% attr(x, "terms") %||% stop("no terms component nor attribute"): ! нет компонента терминов или атрибута. Я пробовал вызвать rlang::ensym на xvar перед функцией, но это ничего не меняет. Не слишком понимаю, что происходит, честно говоря.

user23485480 02.03.2024 18:55

@user23485480 user23485480 Да, я допустил ошибку: конечно rlang::expr() создает неоцененный языковой объект. Нам нужен оцениваемый объект (формула). Мы могли бы либо обернуть результат rlang::expr() в as.formula(), либо в eval(). Или, что гораздо лучше, мы можем использовать rlang::inject() вместо rlang::expr(): эта функция принимает выражение и выполняет интерполяцию через !! и {{…}}, но в остальном выражение вычисляется обычным образом.

Konrad Rudolph 03.03.2024 14:39

Другие вопросы по теме

Похожие вопросы

SQL-запрос к рабочему процессу Arrow DuckDB в R
Асимметричное частичное совпадение текстовых строк между двумя кадрами данных
Разница между rlm() и lm_robust
R — оконное отображение данных в обратном направлении от последних данных в непересекающихся (нескользящих) периодах и подсчет внутри периодов
Р: Как с помощью ggplot построить диаграмму рассеяния различной формы с двумя отдельными переменными?
GForce data.table — применение нескольких функций к нескольким столбцам (с необязательными аргументами)
Как я могу создать перекрестную таблицу по нескольким переменным в R?
Перебирайте евклидовы расстояния, соответствующие идентификатору, используя dist() в R
Как изменить цвет фона графика, сгенерированный графиком (эффект (...)) в сером цвете с белой сеткой в ​​R?
Рассчитайте новый столбец, указав тренд/наклон в других столбцах, используя data.table R