将数据框字符串列拆分为多列(逗号分隔字符)
Split data frame string column into multiple columns (comma separated characters)
我正在尝试将一列以逗号分隔的字符拆分为几列(与总共不同的字符一样多)。
我读到类似的问题,例如:
Split data frame string column into multiple columns
但是解决方案是基于少量可能的字符,因此可以在拆分列之前提前命名新列。
这是我的例子:
subject <- c(1,2,3)
letters <- c("a, b, f, g", "b, g, m, l", "g, m, z")
df1 <- data.frame(subject, letters)
df1
subject letters
1 1 a, b, f, g
2 2 b, g, m, l
3 3 g, m, z
期望的结果是:
subject a b f g m z
1 1 1 1 1 1 0 0
2 2 0 1 0 1 1 0
3 3 0 0 0 1 1 1
在此先感谢您的帮助。
一个选项使用 str_split
、unnest_longer
和 table
subject <- c(1,2,3)
letters <- c("a, b, f, g", "b, g, m, l", "g, m, z")
df1 <- data.frame(subject, letters)
library(tidyverse)
df1 %>%
mutate(letters = str_split(letters, ', ')) %>%
unnest_longer(letters) %>%
table
#> letters
#> subject a b f g l m z
#> 1 1 1 1 1 0 0 0
#> 2 0 1 0 1 1 1 0
#> 3 0 0 0 1 0 1 1
由 reprex package (v2.0.0)
于 2022-02-10 创建
看到其他一些答案,separate_rows
这里是一个更好的解决方案
df1 %>%
separate_rows(letters) %>%
table
A base R 方法 grepl
s unique
字母列表对应 trimws
和 strsplit
的每一行编字母。具有能够轻松地手动与每个步骤交互的优势,以防需要进行任何调整,例如订单更改或遗漏字母等
list_letter <- sapply(strsplit(df1$letters, ","), trimws)
letter <- unique(unlist(list_letter))
letter
[1] "a" "b" "f" "g" "m" "l" "z"
data.frame( subject=df1$subject,
sapply(letter, function(x) sapply(list_letter, function(y)
any(grepl(x, y))))*1 )
subject a b f g m l z
1 1 1 1 1 1 0 0 0
2 2 0 1 0 1 1 1 0
3 3 0 0 0 1 1 0 1
另一种tidyverse
可能性:
library(tidyverse)
df1 %>%
separate_rows(letters) %>%
mutate(value = 1) %>%
pivot_wider(names_from = letters, values_fill = 0)
subject a b f g m l z
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 1 1 1 1 0 0 0
2 2 0 1 0 1 1 1 0
3 3 0 0 0 1 1 0 1
另一个解决方案:
library(dplyr)
library(tidyr)
df1 %>%
mutate(row = row_number()) %>%
separate_rows(letters, sep = ', ') %>%
pivot_wider(names_from = letters, values_from = letters,
values_fn = function(x) 1, values_fill = 0) %>%
select(-row)
# A tibble: 3 × 8
subject a b f g m l z
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 1 1 1 1 0 0 0
2 2 0 1 0 1 1 1 0
3 3 0 0 0 1 1 0 1
我正在尝试将一列以逗号分隔的字符拆分为几列(与总共不同的字符一样多)。 我读到类似的问题,例如:
Split data frame string column into multiple columns
但是解决方案是基于少量可能的字符,因此可以在拆分列之前提前命名新列。
这是我的例子:
subject <- c(1,2,3)
letters <- c("a, b, f, g", "b, g, m, l", "g, m, z")
df1 <- data.frame(subject, letters)
df1
subject letters
1 1 a, b, f, g
2 2 b, g, m, l
3 3 g, m, z
期望的结果是:
subject a b f g m z
1 1 1 1 1 1 0 0
2 2 0 1 0 1 1 0
3 3 0 0 0 1 1 1
在此先感谢您的帮助。
一个选项使用 str_split
、unnest_longer
和 table
subject <- c(1,2,3)
letters <- c("a, b, f, g", "b, g, m, l", "g, m, z")
df1 <- data.frame(subject, letters)
library(tidyverse)
df1 %>%
mutate(letters = str_split(letters, ', ')) %>%
unnest_longer(letters) %>%
table
#> letters
#> subject a b f g l m z
#> 1 1 1 1 1 0 0 0
#> 2 0 1 0 1 1 1 0
#> 3 0 0 0 1 0 1 1
由 reprex package (v2.0.0)
于 2022-02-10 创建看到其他一些答案,separate_rows
这里是一个更好的解决方案
df1 %>%
separate_rows(letters) %>%
table
A base R 方法 grepl
s unique
字母列表对应 trimws
和 strsplit
的每一行编字母。具有能够轻松地手动与每个步骤交互的优势,以防需要进行任何调整,例如订单更改或遗漏字母等
list_letter <- sapply(strsplit(df1$letters, ","), trimws)
letter <- unique(unlist(list_letter))
letter
[1] "a" "b" "f" "g" "m" "l" "z"
data.frame( subject=df1$subject,
sapply(letter, function(x) sapply(list_letter, function(y)
any(grepl(x, y))))*1 )
subject a b f g m l z
1 1 1 1 1 1 0 0 0
2 2 0 1 0 1 1 1 0
3 3 0 0 0 1 1 0 1
另一种tidyverse
可能性:
library(tidyverse)
df1 %>%
separate_rows(letters) %>%
mutate(value = 1) %>%
pivot_wider(names_from = letters, values_fill = 0)
subject a b f g m l z
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 1 1 1 1 0 0 0
2 2 0 1 0 1 1 1 0
3 3 0 0 0 1 1 0 1
另一个解决方案:
library(dplyr)
library(tidyr)
df1 %>%
mutate(row = row_number()) %>%
separate_rows(letters, sep = ', ') %>%
pivot_wider(names_from = letters, values_from = letters,
values_fn = function(x) 1, values_fill = 0) %>%
select(-row)
# A tibble: 3 × 8
subject a b f g m l z
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 1 1 1 1 0 0 0
2 2 0 1 0 1 1 1 0
3 3 0 0 0 1 1 0 1