Замените переменные в формуле их определениями

У меня есть список переменных и соответствующие им определения. У меня также есть предоставленные формулы, но мне бы хотелось, чтобы перевод формул (представленный в примере) лучше понимал, о чем говорит формула. Мой пример упрощен, но обычно у меня около 100 переменных и 100 формул.

Я пытался найти похожие вопросы, но не нашел ответа.

structure(list(variable = c("cs", "csp", "cb", "cc", "ccel", 
"ccrt"), definition = c("cost of salad", "cost of soup", "cost of bread", 
"cost of chicken", "cost of celery", "cost of carrot"), formula = c("cs=cb+ccel+cc", 
"csp=cc+ccel+crt", NA, NA, NA, NA), Translation = c("cost of salad=cost of bread+cost of celery+cost of chicken", 
"cost of soup=cost of chicken+cost of celery+cost of carrot", 
NA, NA, NA, NA)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-6L))

Приведите, пожалуйста, воспроизводимый пример. Данные в изображениях не очень полезны: если я хочу запустить какой-то код, вы теперь просите меня набрать все это из изображения.

Axeman 19.07.2024 19:44
Не публикуйте изображения кода и/или данных. Используйте dput() в своем фрейме данных и скопируйте и вставьте результат в свой пост. Это сделает его более доступным.
LMc 19.07.2024 19:49

Никто не может сказать, есть ли у вас столбец формул/языка или строк. Дайте ему данные

Onyambu 19.07.2024 20:49
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать 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
3
119
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

1) Использование языковых объектов. В R принято преобразовывать выражения в языковые объекты и затем обрабатывать их.

Для этого определите функцию subst, которая

  • вводит и преобразует вектор символов выражений expr в языковые объекты expr2
  • преобразует первые два столбца фрейма данных DF в список имен defs2
  • выполняет замены, используя замену
  • преобразуется обратно в вектор символов с помощью deparse1
  • удаляет обратные кавычки, создаваемые вышеуказанным процессом
  • преобразует "NA" в NA

Таким образом, используя ввод в примечании в конце

subst <- function(expr, defs) {
  expr2 <- lapply(expr, str2lang)
  defs2 <- defs[1:2] |> deframe() |> as.list() |> lapply(as.name)
  s <- sapply(expr2, \(expr) deparse1(do.call(substitute, list(expr, defs2))))
  s <- gsub("`", "", s)
  ifelse(s == "NA", NA, s)
}

# test run
DF %>%
  mutate(translation = subst(formula, pick(variable, definition)))

предоставление

# A tibble: 6 × 4
  variable definition      formula        translation                           
  <chr>    <chr>           <chr>          <chr>                                 
1 cs       cost of salad   cs=cb+ccel+cc  cost of salad = cost of bread + cost …
2 csp      cost of soup    csp=cc+cel+crt cost of soup = cost of chicken + cel …
3 cb       cost of bread   <NA>           <NA>                                  
4 cc       cost of chicken <NA>           <NA>                                  
5 ccel     cost of celery  <NA>           <NA>                                  
6 ccrt     cost of carrot  <NA>           <NA>                                  

2) Мы могли бы также использовать gsubfn для выполнения замен. Мы предполагаем, что переменные полностью состоят из словесных символов. Это дает тот же результат.

library(gsubfn)

subst2 <- function(expr, defs) {
  defs2 <- defs[1:2] |> deframe() |> as.list()
  gsubfn("\\w+", defs2, expr) 
}
 
DF |>
  mutate(translation = subst2(formula, pick(variable, definition)))

Примечание

library(dplyr)
library(tibble)

DF <- tibble(
  variable = c("cs", "csp", "cb", "cc", "ccel", "ccrt"),
  definition = c(
    "cost of salad", "cost of soup", "cost of bread", "cost of chicken",
    "cost of celery", "cost of carrot"
  ),
  formula = c("cs=cb+ccel+cc", "csp=cc+cel+crt", NA, NA, NA, NA),
)

Почему необходима конверсия? Почему этого нельзя сделать с помощью обычных строк?

Azor Ahai -him- 19.07.2024 21:42

Боюсь, я не понимаю вашего объяснения.

Azor Ahai -him- 19.07.2024 21:44

Что ж, мне было любопытно узнать, как вы выбрали первый подход.

Azor Ahai -him- 19.07.2024 22:15

Верно, но это не настоящие формулы в смысле R, верно? Это просто строки, требующие замены, в которых есть = и +. Если я не уловил вашу точку зрения?

Azor Ahai -him- 19.07.2024 22:50

Я люблю это. Теперь я могу быстро сравнивать формулы в программах рядом с их переводом.

Stephen 20.07.2024 01:48

Это можно сделать с помощью str_replace_all из пакета stringr.

Ваши данные содержат два отдельных раздела: переменные+определения и формулы.

Отсортируйте фрейм данных по количеству символов в variable по убыванию.

library(dplyr)
library(stringr)

df <- arrange(df, -nchar(variable))

Создайте именованный вектор переменных, который будет использоваться в качестве аргумента шаблона.

pattern <- setNames(df$definition, df$variable)

forms <- as.list(na.omit(df$formulas)
forms
#[[1]]
#[1] "csp=cc+ccel+crt"

#[[2]]
#[1] "cs=cb+ccel+cc"

lapply(forms, \(x) str_replace_all(x, pattern))
#[[1]]
#[1] "cost of soup=cost of chicken+cost of celery+cost of carrot"

#[[2]]
#[1] "cost of salad=cost of bread+cost of celery+cost of chicken"

Данные

df <- structure(list(variable = c("ccel", "ccrt", "csp", "cs", "cb", 
"cc"), definition = c("cost of celery", "cost of carrot", "cost of soup", 
"cost of salad", "cost of bread", "cost of chicken"), formula = c(NA, 
NA, "csp=cc+ccel+ccrt", "cs=cb+ccel+cc", NA, NA), Translation = c(NA, 
NA, "cost of soup=cost of chicken+cost of celery+cost of carrot", 
"cost of salad=cost of bread+cost of celery+cost of chicken", 
NA, NA)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-6L))

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