Проверить, совпадает ли элемент таблицы с именем столбца

#r #dplyr

#r #dplyr

Вопрос:

У меня есть следующие данные:

 data <- tibble(
  product_01 = c("AB", "AC", NA),
  product_02 = c("AD", NA, "AB"),
  AB = NA,
  AC = NA,
  AD = NA)
  

Теперь я хочу получить следующую информацию:

 > data
# A tibble: 3 x 5
  product_01 product_02 AB    AC    AD   
  <chr>      <chr>      <lgl> <lgl> <lgl>
1 AB         AD         TRUE  FALSE TRUE   
2 AC         NA         FALSE TRUE  FALSE   
3 NA         AB         TRUE  FALSE FALSE
  

т.е. для каждого элемента строки (в столбцах, начинающихся с product ) проверьте, совпадает ли этот элемент с именем столбца (после столбцов, начинающихся с product), и укажите TRUE , совпадает ли он или FALSE нет. У кого-нибудь есть идеи, как поступить здесь? Я попробовал некоторый код (в основном с lapply ), но безрезультатно. заранее спасибо

Ответ №1:

Вы можете использовать apply :

 cols <- names(data)[-(1:2)]
data[cols] <- t(apply(data[1:2], 1, function(x)  cols %in% x))

# product_01 product_02    AB    AC    AD   
#  <chr>      <chr>      <lgl> <lgl> <lgl>
#1 AB         AD         TRUE  FALSE TRUE 
#2 AC         NA         FALSE TRUE  FALSE
#3 NA         AB         TRUE  FALSE FALSE
  

Я думаю, что в общем случае мы бы не создали столбцы со NA значениями.

 data <- tibble(
  product_01 = c("AB", "AC", NA),
  product_02 = c("AD", NA, "AB"))
  

Затем мы можем использовать dplyr и tidyr следующим образом :

 library(dplyr)
library(tidyr)

data1 <- data %>% mutate(row = row_number())

data1 %>%
  pivot_longer(cols = -row,
               values_drop_na = TRUE) %>%
  mutate(val = TRUE) %>%
  select(-name) %>%
  pivot_wider(names_from = value, values_from = val, values_fill = FALSE) %>%
  left_join(data1, by = 'row')
  

Комментарии:

1. Привет, Ронак, спасибо :). Как вы думаете, есть ли решение dplyr для этой проблемы?

2. Это не однострочный, но я обновил ответ dplyr tidyr решением и. @danish

3. Спасибо Ronak. С благодарностью

Ответ №2:

dplyr Попытка, которая сработает, но мне не очень удобно использовать циклы, поэтому она немного длинная

 library(tidyverse)

data2 <- data %>% mutate(row_id = row_number()) %>% 
  select(-AB, -AC, -AD) %>%
  pivot_longer(cols = c(product_01, product_02), names_to ='name', values_to = "val") %>%
  filter(!is.na(val)) %>%
  mutate(val2 = TRUE) %>%
  pivot_wider(id_cols = row_id, names_from = val, 
values_from = val2, values_fill =FALSE) 

data %<>% mutate(row_id = row_number()) %>% 
  select(-AB, -AC, -AD) %>%
  left_join(data2, by = "row_id") %>%
  select(-row_id)

# A tibble: 3 x 5
  product_01 product_02 AB    AD    AC   
  <chr>      <chr>      <lgl> <lgl> <lgl>
1 AB         AD         TRUE  TRUE  FALSE
2 AC         NA         FALSE FALSE TRUE 
3 NA         AB         TRUE  FALSE FALSE
  

Комментарии:

1. Я только что заметил, что Ronak также дал решение в аналогичных строках лучшим способом. 🙂