Как заменить строку специального символа в фрейме данных? р

У меня есть следующий фрейм данных под названием result.

РУКОВОДСТВО.ID АВТО.ID место нет данных ПИППИП L2 Пип пип нет данных L1 Барбара нет данных L5 нет данных Пип пип L3 нет данных Пиппип,БарБар L3

Я пытаюсь заменить все разные формы одного и того же тега правильным. Например, замените все PIPPIP и PIPpip на Pippip или Berbar на Barbar. Для этого я использую функцию mutate с left_join на основе требуемого файла с именем tesaurus, в котором есть столбец со всеми возможными случаями одного и того же тега (tag_id) и столбец с правильным (tag_ok), который выглядит следующим образом:

tag_id tag_ok ПИППИП Пип пип Пип пип Пип пип Пип пип Пип пип Барбара Барбара БерБар Барбара

Я использую следующий код.

library("plyr")
library("dplyr")
library("reshape")
library("data.table")
library("stringr")
library("tidyr")
library("openxlsx")

tesaurus <- read.xlsx("Requested_files/sp_tesaurus.xlsx", sheet = "tesaurus") %>%
  select(-bat_sp)

result <- result %>%
  left_join(tesaurus, by = c(MANUAL.ID = "tag_id")) %>%
  mutate(MANUAL.ID = coalesce(tag_ok, MANUAL.ID)) %>%
  select(-tag_ok) %>%
  left_join(tesaurus, by = c(AUTO.ID = "tag_id")) %>%
  mutate(AUTO.ID = coalesce(tag_ok, AUTO.ID)) %>%
  select(-tag_ok)

Этот код хорошо работает для столбца MANUAL.ID, но для столбца AUTO.ID из-за особого случая: Pippip,BerBar (в одном случае два тега)

Как я могу это исправить?

Это не совсем подходит для всех ваших случаев, но я считаю, что стоит упомянуть str_to_title() из пакета stringr, который правильно изменит все слова на заглавные (заглавные только в первом символе). Если бы у нас не было дополнительных замен, таких как PYPPYP > Pippip , мы могли бы даже избавиться от необходимости в таблице поиска.

GuedesBF 14.04.2023 17:03
Стоит ли изучать 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
1
59
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Мы могли бы сделать это так: Примечание. Я думаю, что в тезаурусе Barbar в tag_id должно быть Berbar:

tesaurus <- structure(list(tag_id = c("PYPPYP", "PIPpip", "Pippip", "Barbar", 
"BerBar"), tag_ok = c("Pippip", "Pippip", "Pippip", "Barbar", 
"Barbar")), class = "data.frame", row.names = c(NA, -5L))

данные:

df <- structure(list(MANUAL.ID = c(NA, "PIPpip", "Barbar", NA, NA), 
    AUTO.ID = c("PYPPYP", NA, NA, "Pippip", "Pippip,BerBar"), 
    loc = c("L2", "L1", "L5", "L3", "L3")), class = "data.frame", row.names = c(NA, 
-5L))

Решение:

library(dplyr)
library(stringr)
library(tidyr)

df %>% 
  mutate(id = row_number()) %>% 
  separate_rows(everything()) %>% 
  group_by(id) %>% 
  mutate(row = row_number()) %>% 
  ungroup() %>% 
  mutate(across(-c(loc, id, row), ~ifelse(str_detect(., paste(tesaurus$tag_id, collapse = "|")),
                              tesaurus$tag_ok, .)
  )) %>% 
  arrange(id, -row) %>% 
  summarise(across(everything(), ~toString(., na.rm=TRUE)), .by = c(id, loc)) %>% 
  mutate(across(-c(id, loc), ~ifelse(str_detect(., "NA"), NA_character_, .))) %>% 
  select(contains("ID"), loc, -id)
  
  MANUAL.ID AUTO.ID        loc  
  <chr>     <chr>          <chr>
1 NA        Pippip         L2   
2 Pippip    NA             L1   
3 Pippip    NA             L5   
4 NA        Barbar         L3   
5 NA        Pippip, Barbar L3 

но таким образом результат в 5-й строке (столбец AUTO.ID) - это просто Пиппип, а ожидаемый должен быть Пиппип, Барбар

lobarth 14.04.2023 16:47

Нет, для столбца 5-й строки AUTO.ID ожидаемый результат должен быть Pippip, Barbar, а не Pippip, BarBar.

lobarth 14.04.2023 17:06

Хорошо, я только что обновил tesaurus. Код работает!

TarJae 14.04.2023 17:11

Мы могли бы использовать str_replace_all с именованным вектором

library(dplyr)
library(stringr)
library(tibble)
df %>% 
  mutate(across(ends_with("ID"), ~ str_replace_all(.x, deframe(tesaurus))))

-выход

   MANUAL.ID       AUTO.ID loc
1      <NA>        Pippip  L2
2    Pippip          <NA>  L1
3    Barbar          <NA>  L5
4      <NA>        Pippip  L3
5      <NA> Pippip,Barbar  L3

это решение заменяет все столбцы aAUTO.ID и MANUAL.ID на NA

lobarth 14.04.2023 17:22

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