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

#r #merge #matching #calculated-columns #refer

#r #слияние #сопоставление #вычисляемые столбцы #обратитесь

Вопрос:

У меня есть таблица, такая как

  --------- --------- -------- -------- -------- 
| Product | Classif | Type 1 | Type 2 | Type 3 |
 --------- --------- -------- -------- -------- 
| a       | Type 1  |      2 |      6 |      8 |
| b       | Type 2  |      3 |      9 |     11 |
| c       | Type 3  |      5 |     10 |     15 |
 --------- --------- -------- -------- -------- 

  

Где у меня есть список продуктов и классификация, которую они имеют. Совпадения между продуктом и классификацией достаточно для определения их цены (которая указана в столбцах с 3 по 5).
Я хотел бы создать новый столбец, который показывает цену каждого продукта в соответствии с его типом, например:

  --------- --------- -------- -------- -------- ------- 
| Product | Classif | Type 1 | Type 2 | Type 3 | Price |
 --------- --------- -------- -------- -------- ------- 
| a       | Type 1  |      2 |      6 |      8 |     2 |
| b       | Type 2  |      3 |      9 |     11 |     9 |
| c       | Type 3  |      5 |     10 |     15 |    15 |
 --------- --------- -------- -------- -------- ------- 

  

Где программа сравнивает значение classif столбца и берет значение из соответствующего столбца.

Ответ №1:

То, что вы ищете, может быть достигнуто путем преобразования ваших данных сначала в long, а затем вычисления сравнения для получения цены, чтобы объединить все вместе left_join() . Здесь код, использующий tidyverse функции:

 library(tidyverse)
#Code
df2 <- df %>% left_join(df %>% pivot_longer(-c(Product,Classif)) %>%
  mutate(Price=ifelse(Classif==name,value,NA)) %>%
  filter(!is.na(Price)) %>% select(-c(name,value)))
  

Вывод:

   Product Classif Type 1 Type 2 Type 3 Price
1       a  Type 1      2      6      8     2
2       b  Type 2      3      9     11     9
3       c  Type 3      5     10     15    15
  

Некоторые используемые данные:

 #Data
df <- structure(list(Product = c("a", "b", "c"), Classif = c("Type 1", 
"Type 2", "Type 3"), `Type 1` = c(2, 3, 5), `Type 2` = c(6, 9, 
10), `Type 3` = c(8, 11, 15)), row.names = c(NA, -3L), class = "data.frame")
  

Ответ №2:

Работает ли это?

 library(data.table)

df <- data.table(Product = c('a', 'b', 'c'), 
             Classif = c('Type 1', 'Type 2', 'Type 3'),
             `Type 1` = c(2, 3, 5),
             `Type 2` = c(6,9,10),
             `Type 3` = c(8,11,15)
             )


df2 <- df[,`:=`(
  Price = case_when(
     Classif == 'Type 1' ~ `Type 1`,
     Classif == 'Type 2' ~ `Type 2`,
     Classif == 'Type 3' ~ `Type 3`
  )
)]
  

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

1. case_when требуется dplyr, но, к вашему сведению, текущая версия данных.в таблице 1.13 теперь есть функция case fcase (на случай, если вы хотите использовать только один пакет)