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

У меня есть 2 фрейма данных, каждый из которых я хочу использовать в качестве условия для применения во втором фрейме данных. Вот их пример:

condition_df <- data.frame(
  type = c("3701","3801","4901","4901", "3701"),
  position = c(51,51, 22,22, 13),
  subtype = c("M", "M","D","K", "E")
)
df <- data.frame(
  id = 1:5,
  type1 = c("3701", "4901", "4902", "4903", "1501"),
  type2 = c("3801", "4901", "4901","5050","6069"),
  type3 = c("3901", "5001", "8901","5050","6069"),
  type4 = c("4001", "3901", "7901","5050","6069"),
  `51` = c("M", "A", "M", "M", "A"),
  `22` = c("D", "D", "K", "A", "D"),
  `13` = c("E", "G", "E", "E", "G"),
  `55` = c("M", "A", "M", "M", "A"),
  `25` = c("D", "D", "K", "A", "D"),
  `16` = c("E", "G", "E", "E", "G"), check.names = FALSE
)

поэтому я хочу получить оценку во втором фрейме данных (df), и я хочу ее применить, используя строки фрейма данных условия для цикла по каждой строке фрейма данных. Условие состоит в том, что если тип отсутствует в столбцах df (type1:type4), то найдите столбец с именем == позиции (в условии_df) и подсчитайте количество букв в этом столбце, которые совпадают только с подтип в условии_df. Итоговая оценка должна представлять собой сумму всех условий Condition_df для каждого идентификатора в df. Пример. Оценка идентификатора 1 равна только 1, поскольку мы получили 0 для первого и последнего условий (поскольку у него есть тип, поэтому мы игнорируем подтип) и получили 1, поскольку он имеет второй подтип «D» и не имеет его типа. Любая помощь приветствуется.

Я попробовал что-то вроде этого, но не сработало:

for(i in seq_len(nrow(condition_df))) {
  for(j in seq_len(nrow(df))) {
    type <- condition_df$type[i]
    position <- as.character(condition_df$position[i])
    subtype <- condition_df$subtype[i]
    
    df<-df %>% 
      mutate(cir_score=case_when(!any(across(starts_with("type"))==type)~sum(get(as.character(position))==subtype),
                                 
                                 TRUE~0
      ))
      
  }
} 

Не могли бы вы опубликовать желаемый результат?

user2974951 22.07.2024 11:02

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

Marwah Al-kaabi 23.07.2024 05:11
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Поверните в длинную форму столбцы позиций (51, 22, ...), а затем присоединитесь к фрейму данных условия. Затем отфильтруйте строки, в которых тип соответствует типам 1–4, тогда оценка будет равна количеству записей, оставшихся для каждого идентификатора.

full_join(df,
      pivot_longer(df, -c(id, starts_with("type")),
                   names_to = "position", values_to = "subtype",
                   names_transform=list(position=as.integer)) |>
       inner_join(condition_df, by=c("position", "subtype"), relationship = "many-to-many") |> 
       filter(!if_any(matches("type\\d+"), ~ .x==type)) |>
       distinct(id, position, subtype) |>
       count(id, name = "score"),
          by = "id") |>
  mutate(score=replace_na(score, 0))

  id type1 type2 type3 type4 51 22 13 55 25 16 score
1  1  3701  3801  3901  4001  M  D  E  M  D  E     1
2  2  4901  4901  5001  3901  A  D  G  A  D  G     0
3  3  4902  4901  8901  7901  M  K  E  M  K  E     2
4  4  4903  5050  5050  5050  M  A  E  M  A  E     2
5  5  1501  6069  6069  6069  A  D  G  A  D  G     1

Большое спасибо за публикацию этого ответа. Ожидаемый результат (оценка) правильный; однако я попробовал код на своих реальных данных, но, к сожалению, он не сработал. Проблема в том, чтоcondition_df может иметь несколько значений типа для одной и той же позиции, и это не обнаруживается с помощью внутреннего соединения. Есть ли способ изменить этот код? Было бы здорово, если бы решение включало случай, когда я мог бы добавить больше условий на случай отсутствия доступных значений. Очень ценю вашу помощь.

Marwah Al-kaabi 23.07.2024 05:10

@Эрвард, я получил это предупреждение, когда проводил анализ моих реальных данных In full_join(., condition_df2) : Detected an unexpected many-to-many relationship between x` и y. ℹ Строка 120 из x соответствует нескольким строкам из y. ℹ Строка 13 y соответствует нескольким строкам x. ℹ Если ожидается связь «многие-ко-многим», установите relationship = "many-to-many", чтобы отключить это предупреждение.`

Marwah Al-kaabi 23.07.2024 05:10

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

Edward 23.07.2024 05:11

Да, это правда, я пропустил это и попытаюсь привести новый пример. Спасибо

Marwah Al-kaabi 23.07.2024 05:13

Я отредактировал фрейм данных условия, чтобы он был максимально приближен к моим реальным данным. Извините, я это пропустил.

Marwah Al-kaabi 23.07.2024 05:33

Смотрите обновление. Возможно, сейчас это не лучший способ.

Edward 23.07.2024 06:00

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