1 r dataframe tidyr data-cleaning
我正在处理以标签为特征的产品数据集。也就是说,它们有一个由逗号分隔的单词列表组成的属性。例如,
data.frame(
id = c(11, 12, 13),
tags =c("wood,small,old","big,iron,artistic", "pretty,wood")
)
Run Code Online (Sandbox Code Playgroud)
我想将标签列分成每个标签的不同逻辑列,即
| id | wood | iron | small | big | old | artistic | pretty |
------------------------------------------------------------
| 11 | TRUE| FALSE| TRUE| FALSE| TRUE| FALSE| FALSE|
| 12 | FALSE| TRUE| FALSE| TRUE| FALSE| TRUE| FALSE|
| 13 | TRUE| FALSE| FALSE| FALSE| FALSE| FALSE| TRUE|
Run Code Online (Sandbox Code Playgroud)
我尝试使用包中的separate函数tidyr,但标签是无序的,很难为每个标签做一列。
我找到了一个使用mutatefromdplyr包并为每个标签手动创建一列的解决方案,
has_tag <- function(tag, tags) {
strsplit(tags, ",") %>% map_lgl(function(x) tag %in% x)
}
df %>%
mutate(
wood = has_tag("wood", tags),
iron = has_tag("iron", tags),
...
)
Run Code Online (Sandbox Code Playgroud)
但是将来可能会出现新标签,我想让它具有可扩展性。
¿有什么方法可以轻松做到吗?
你可以这样做:
library(tidyverse)
df %>%
separate_rows(tags) %>%
mutate(val = TRUE) %>%
spread(tags, val, FALSE)
id artistic big iron old pretty small wood
1 11 FALSE FALSE FALSE TRUE FALSE TRUE TRUE
2 12 TRUE TRUE TRUE FALSE FALSE FALSE FALSE
3 13 FALSE FALSE FALSE FALSE TRUE FALSE TRUE
Run Code Online (Sandbox Code Playgroud)
使用基础 R 它需要一些步骤:
as.data.frame.matrix(xtabs(f~ind+values,
cbind(stack(setNames(strsplit(as.character(df$tags),","),df$id)),f = 1))>0)
artistic big iron old pretty small wood
11 FALSE FALSE FALSE TRUE FALSE TRUE TRUE
12 TRUE TRUE TRUE FALSE FALSE FALSE FALSE
13 FALSE FALSE FALSE FALSE TRUE FALSE TRUE
Run Code Online (Sandbox Code Playgroud)