首页 > 解决方案 > 从长(具有多个类别)到宽格式

问题描述

我有一个长格式的数据框,其中每列可以采用多个值(用逗号分隔):

dataset_long = data.frame(id=1:5, type=c("A", "A, B", "C, A", "C", "A"))

> dataset_long id type 1 1 A 2 2 A, B 3 3 C, A 4 4 C 5 5 A

我想将其转换为广泛的格式,以用于回归:

dataset_wide = data.frame(id=1:5, type_A = c(1,1,1,0,1), type_B = c(0,1,0,0,0), type_C = c(0,0,1,1,0))

> dataset_wide id type_A type_B type_C 1 1 1 0 0 2 2 1 1 0 3 3 1 0 1 4 4 0 0 1 5 5 1 0 0

它在某种程度上类似于“一个热编码”,但每一行可能属于几个类别。

有什么优雅的方式可以从dataset_longdataset_wide吗?

标签: r

解决方案


这段代码将产生您在示例中显示的结果

library(tidyverse)

dataset_long = data.frame(id=1:5, type=c("A", "A, B", "C, A", "C", "A"))

dataset_wide <- dataset_long %>% mutate(type_A=ifelse(regexpr('A', type)>0, 1, 0), 
                                        type_B=ifelse(regexpr('B', type)>0, 1, 0), 
                                        type_C=ifelse(regexpr('C', type)>0, 1, 0))
dataset_wide
#>   id type type_A type_B type_C
#> 1  1    A      1      0      0
#> 2  2 A, B      1      1      0
#> 3  3 C, A      1      0      1
#> 4  4    C      0      0      1
#> 5  5    A      1      0      0

reprex 包(v0.2.1)于 2019 年 2 月 2 日创建

但是,这不是数据集的“从长到宽”的重新排列。您的原始 dataset_long 和新 dataset_wide 每个 ID 都有一行。通常,当我们说“长”时,我们谈论的是每个 ID 多行被折叠成“宽”格式,每个 ID 一行。

大多数人会称之为简单地创建三个指示(或虚拟)变量,表示原始文本字符串中存在 A、B 或 C。

PS 我使用 ifelse() 和 regexpr()>0 几乎肯定不是创建这三个指标变量的最简洁的方法。这些只是我通常在自己的代码中默认使用的功能。


推荐阅读