我有一个数据集,每一行都有一个包含元素数组的单元格。我想将该数组分解为单独的元素,并将行复制与数组长度一样多的次数,并逐个填充数组元素代替数组。
我有什么:
示例 A 列 | B列 |
---|---|
名字 1 | [“A”、“B”、“C”] |
我想要的:
示例 A 列 | B列 |
---|---|
名字 1 | “A” |
名字 1 | “乙” |
名字 1 | “C” |
R 或 Python 代码优先,但 Excel 也可以工作
你可以用
data.table
做到这一点。
df = data.table(colA = "name 1",
colB = "[\"A\", \"B\", \"C\"]")
df[,.(colA,
colB = sapply(tstrsplit(gsub("[[:punct:]]","",colB)," "), `[` ))]
输出
colA colB
<char> <char>
1: name 1 A
2: name 1 B
3: name 1 C
此方法的工作流程如下:
str_replace_all()
从 stringr
包中删除所有特殊字符separate_wider_delim()
将每个字母分成单独的列pivot_longer()
为每个组的每个值创建行library(stringr)
library(dplyr)
library(tidyr)
# Example dataframe based on your example
df <- data.frame(colA = "name 1",
colB = "[\"A\", \"B\", \"C\"]")
df %>%
mutate(colB = str_replace_all(colB, "[[:punct:]]", "")) %>%
separate_wider_delim(colB,
" ",
names = c(paste0("col", (1:3))),
too_few = "align_start") %>%
pivot_longer(!colA, values_to = "colB") %>%
select(-name)
# A tibble: 3 × 2
# colA colB
# <chr> <chr>
# 1 name 1 A
# 2 name 1 B
# 3 name 1 C
# Example dataframe with varying list lengths (in case values in "colB" vary)
df <- data.frame(colA = c("name 1", "name 2"),
colB = c("[\"A\", \"B\", \"C\"]",
"[\"A\", \"B\", \"C\"], \"D\"]"))
df %>%
mutate(colB = str_replace_all(colB, "[[:punct:]]", "")) %>%
separate_wider_delim(colB,
" ",
names = c(paste0("col", (1:4))),
too_few = "align_start") %>%
pivot_longer(!colA, values_to = "colB") %>%
filter(!is.na(colB)) %>%
select(-name)
# A tibble: 7 × 2
# colA colB
# <chr> <chr>
# 1 name 1 A
# 2 name 1 B
# 3 name 1 C
# 4 name 2 A
# 5 name 2 B
# 6 name 2 C
# 7 name 2 D
请注意,如果您在“colB”中的字符长度不同,则
too_few = "align_start"
。此外,您可能需要编辑names = c(paste0("col", (1:n)))
,其中n是“colB”中值的最大长度。
我知道这不是首选,但您可以使用 excel 中的公式:
=LET(string, B1,
clean, MID(string,2,LEN(string)-2),
split, TEXTSPLIT(clean,,", "),
HSTACK( EXPAND(A1,
ROWS(split),
,
A1),
split))
其中
B1
中的字符串从第一个和最后一个字符[
和]
中删除。
而不是拆分成一个单独的字符串数组。
A1中的值展开的次数等于创建数组的行数。
这两个水平堆叠在一起就是想要的结果。