【问题标题】:Is there an R function that can convert a existing metric into a new logical metric?是否有可以将现有指标转换为新逻辑指标的 R 函数?
【发布时间】:2020-03-05 23:48:28
【问题描述】:

我有一个来自 Pokemon 统计数据的数据集,其中包含大量数字和分类数据。我的最终目标是创建一个模型或推荐系统,用户可以输入口袋妖怪列表,该模型会找到他们可能喜欢的类似口袋妖怪。目前数据集看起来像这样:

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

我知道 type1/type2 指标可能有问题,是否有一个函数可以让我创建一个新的创建/修改新列,如果口袋妖怪具有特定类型,它将添加一个逻辑值(0 表示 false,1为真)在那个新列中?

我为缺乏精彩的解释道歉,但我希望我的数据集看起来像这样:

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

【问题讨论】:

标签: r function wrangle


【解决方案1】:

tidyr 是一个数据重塑包。在这里,我们将使用pivot_longer() 将其转换为长格式,其中类型名称(Type1、Type2)将驻留在“name”列中,而值(Grass、Poison 等)将驻留在“列”中价值”。我们 过滤掉带有is.na(value) 的行,因为这意味着口袋妖怪没有第二种类型。我们创建了一个指标变量——它得到一个 1。然后每个 pokemon 将有 indicator == 1 来表示它所拥有的类型。我们删除现在无关的“名称”列,并使用pivot_wider()value 中的每个唯一值转换为它自己的列,该列将接收indicator 的值作为每一行的单元格值。最后,我们对所有数字列进行变异以用 0 替换缺失值,因为我们知道那些 pokemon 不是那些类型。 比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

【讨论】:

  • 在最后一步中,您使用mutate_if 的方式也会捕获 HP 和 ID — 这可能会成为一个问题,因为您正在处理您实际上并不打算更改的列。使用mutate_at 并明确选择您想要的列,或者选择例如,可能会更安全。 -ID:-HP。此时,由于您要从逻辑条件中生成数字 0/1,因此您可以将 ifelse 简化为 as.numeric(!is.na(x))
  • 公平积分。我在上一段中介绍了mutate_if()mutate_at()
猜你喜欢
  • 2020-08-12
  • 1970-01-01
  • 2020-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-08
  • 2021-10-11
相关资源
最近更新 更多