Ищите текстовое поле и заменяйте его значением из столбца - PullRequest
1 голос
/ 28 марта 2020

У меня есть фрейм данных, и мне нужно найти в последнем столбце имена столбцов других столбцов и заменить найденный текст значением из соответствующего столбца. Используя приведенные ниже примеры данных, первая строка будет работать следующим образом:

  • текст «дата» следует заменить на «2019-05-12» в столбце Query
  • текст «заменить» должен быть заменен на «1» в Query столбце
  • текст «нижний» должен быть заменен на «150» в Query столбце
  • текст «верхний» следует заменить на «250» в столбце Query

Я пробовал функцию str_replace из stringr, но она не сработала, возможно, я неправильно использую функцию. Любая помощь приветствуется, спасибо.

data=structure(list(date = c("2019-05-12", "2019-07-10", "2019-04-10"
), substitute = c(1, 2, 3), lower = c(150, 100, 300), upper = c(250, 
                                                                200, 400), query = c("Select \r\ncolumn1,\r\ncolumn2,\r\ncase \r\nwhen \"date\" between a and b then 1\r\nwhen \"date\" between c and d then 2\r\nend as date_group,\r\ncase when \"date\" < e then \r\n'substitute' as ID\r\nFROM Table1\r\nWHERE (date_2 between a and d )\r\n      AND (tag between 'lower' and 'upper')\r\nGROUP BY", 
                                                                                     "Select \r\ncolumn1,\r\ncolumn2,\r\ncase \r\nwhen \"date\" between a and b then 1\r\nwhen \"date\" between c and d then 2\r\nend as date_group,\r\ncase when \"date\" < e then \r\n'substitute' as ID\r\nFROM Table1\r\nWHERE (date_2 between a and d )\r\n      AND (tag between 'lower' and 'upper')\r\nGROUP BY", 
                                                                                     "Select \r\ncolumn1,\r\ncolumn2,\r\ncase \r\nwhen \"date\" between a and b then 1\r\nwhen \"date\" between c and d then 2\r\nend as date_group,\r\ncase when \"date\" < e then \r\n'substitute' as ID\r\nFROM Table1\r\nWHERE (date_2 between a and d )\r\n      AND (tag between 'lower' and 'upper')\r\nGROUP BY"
                                                                )), row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame"
                                                                ))

Ответы [ 2 ]

2 голосов
/ 28 марта 2020

Мы можем обернуть {} вокруг имен столбцов в query и оценить его по строкам, используя glue.

library(dplyr)
library(stringr)
library(glue)

output_data <- data %>%
   mutate(query_new = str_replace_all(query, paste0('\\b',names(.), '\\b',
                       collapse = "|"), function(m) paste0('{', m, '}'))) %>%
   rowwise() %>%
   mutate(query_new = as.character(glue(query_new)))


cat(output_data$query_new[1])

#Select 
#column1,
#column2,
#case 
#when "2019-05-12" between a and b then 1
#when "2019-05-12" between c and d then 2
#end as date_group,
#case when "2019-05-12" < e then 
 #'1' as ID
#FROM Table1
#WHERE (date_2 between a and d )
#      AND (tag between '150' and '250')
#GROUP BY
1 голос
/ 28 марта 2020

Используйте apply для каждого столбца:

rep_fun = function(df_row){
  df_row[5] = gsub("\"date\"",df_row[1],df_row[5])
  df_row[5] = gsub("substitute",df_row[2],df_row[5])
  df_row[5] = gsub("lower",df_row[3],df_row[5])
  df_row[5] = gsub("upper",df_row[4],df_row[5])
}
data[,"query"] = apply(data,1,rep_fun)
data
...