Есть ли функция R, которая может преобразовать существующую метрику в новую логическую метрику?

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

ID   Name    Type1    Type2   HP 
001  Bulba.. Grass    Poison  45
ect...

Я понимаю, что метрика type1/type2 может быть проблематичной.Есть ли функция, которая позволила бы мне создать новый создать / изменить новые столбцы, если бы у Pokemon был определенный тип, он бы добавил логическое значение (0 для false, 1 для true) в этом новом столбце?

Я прошу прощения за отсутствие блеска, но я хочу, чтобы мой набор данных выглядел так:

ID   Name    Grass  Poison Water  HP 
001  Bulba..    1      1     0    45
ect...

1 ответ

Решение

Tidyr - это пакет для преобразования данных. Здесь мы будем использоватьpivot_longer()чтобы поместить его в длинный формат, где имена типов (Тип1, Тип2) будут находиться в столбце "имя", а значения (Трава, Яд и т. д.) будут находиться в столбце "Значение". Мы отфильтровываем строки с помощьюis.na(value)потому что это означает, что у покемонов не было второго типа. Мы создаем индикаторную переменную - она ​​получает 1. У каждого покемона будетindicator == 1для типов, которые у него есть. Мы отбрасываем лишний теперь столбец "имя" и используемpivot_wider() преобразовать каждое уникальное значение в value в свой столбец, который получит indicatorзначение как значение ячейки для каждой строки. Наконец, мы изменяем все числовые столбцы, чтобы заменить пропущенные на 0, так как мы знаем, что эти покемоны не относятся к этим типам. Лучшее решение, чемmutate_if(is.numeric, ...) будет вычислять уникальные значения типов и использовать mutate_at(vars(pokemon_types), .... Это не повлияет непреднамеренно на другие числовые столбцы.

library(tidyr)
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
pokemon <- tibble(ID = c(1,2), Name = c("Bulbasaur", "Squirtle"),
                  Type1 = c("Grass", "Water"), 
                  Type2 = c("Poison", NA),
                  HP = c(40, 50))

pokemon %>% pivot_longer(
  starts_with("Type")
) %>% 
  filter(!is.na(value)) %>% 
  mutate(indicator = 1) %>% 
  select(-name) %>% 
  pivot_wider(names_from = value, values_from = indicator,
              ) %>% 

  mutate_if(is.numeric, .funs = function(x) if_else(is.na(x), 0, x))
#> # A tibble: 2 x 6
#>      ID Name         HP Grass Poison Water
#>   <dbl> <chr>     <dbl> <dbl>  <dbl> <dbl>
#> 1     1 Bulbasaur    40     1      1     0
#> 2     2 Squirtle     50     0      0     1
Другие вопросы по тегам