Вот простое базовое решение R (пояснение ниже):
spl <- with(df1, strsplit(as.charcter(B), split = "; ", fixed = TRUE))
lens <- sapply(spl, length)
out <- with(df1, data.frame(A = rep(A, lens), B = unlist(spl)))
Что дает нам:
R> out
A B
1 aaa 111
2 aaa 222
3 bbb 333
4 ccc 444
5 ccc 555
6 ccc 666
7 ccc 777
8 ddd 888
9 ddd 999
Что делает код? Строка 1:
spl <- with(df1, strsplit(as.character(B), split = "; ", fixed = TRUE))
разбивает каждую строку в B
, используя "; "
в качестве символов для разделения. Мы используем fixed = TRUE
(как предложено @ Marek в комментариях) для ускорения сопоставления и разделения, так как в этом случае нам не нужно сопоставлять с помощью регулярного выражения, мы просто хотим сопоставить на указанная строка. Это дает нам список с разделением различных элементов:
R> spl
[[1]]
[1] "111" "222"
[[2]]
[1] "333"
[[3]]
[1] "444" "555" "666" "777"
[[4]]
[1] "888" "999"
Следующая строка просто подсчитывает, сколько элементов есть в каждом компоненте списка spl
lens <- sapply(spl, length)
, который дает нам векторы длин:
R> lens
[1] 2 1 4 2
Последняя строка решения включает выходные данные двух предыдущих шагов в новый фрейм данных. Хитрость заключается в том, чтобы повторять каждый элемент df1$A
lens
количество раз; для которого мы используем функцию rep()
. Нам также нужно развернуть список spl
в вектор, который мы делаем с unlist()
:
out <- with(df1, data.frame(A = rep(A, lens), B = unlist(spl)))