Разделение столбца с несколькими и неравномерно распределенными разделителями в R
У меня есть столбец / вектор символьных данных, которые мне нужно разделить на разные столбцы. Эта проблема? Существуют разные разделители (которые означают разные вещи) и разные длины между каждым разделителем. Например:
column_name
akjhaa 1-29 y 12-30
bsd, 14-20
asdf asdf del 2-5 y 6
dkljwv 3-31
joikb 6-22
sqwzsxcryvyde jd de 1-2
pk, ehde 1-2
jsd 1-15
asdasd asedd 1,3
Числа должны быть разделены на столбцы отдельно от символов. Тем не менее, числа могут быть разделены запятой или тире или "у". Более того, числа, разделенные тире, должны быть как-то обозначены, так как в конечном итоге мне нужно создать документ / вектор, в котором каждое из чисел в этом диапазоне находится также в своем собственном столбце (так, чтобы столбец с разделенным aaa стал aaa 1 2 3 4 5 .... 29 12 13 ... 30).
До сих пор я пытался разделить столбцы на основе разных разделителей, но поскольку иногда значения имеют более одного "-", "y" или "y" попадает как слово в одну из первых частей символа, начинает становиться немного сложнее... есть ли более простой способ?
Для пояснения, в конкретном "столбце-имени", которое я дал, конечный результат будет таким, что у меня будет n столбцов, где n = (наибольшее число чисел + 1 (строка символов имени столбца)). Итак, в примере с предоставленным "column_name" это будет выглядеть так:
column_name n1 n2 n3 n4 n5 n6 n7 n8 n9 n10 n11 n12 n13 n14 n15 n16 n17 n18 n19 n20 n21 n22 n23 n24 n25 n26 n27 n28 n29 n30 n31 n32 n33 n34 n35 n36 n37 n38 n39 n40 n41 n42 n43 n44 n45 n46 n47 n48 n49 n50 n51 n52 n53 n54 n55 n56 n57 n58
akjhaa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
bsd 14 15 16 17 18 19 20
asdf asdf del 2 3 4 5 6
dkljwv 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
joikb 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
sqwzsxcryvyde jd de 1 2
pk ehde 1 2
jsd 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
asdasd asedd 1 3
1 ответ
Это не красиво, но это работает. Результатом является list
столбец с соответствующими значениями.
library(magrittr)
library(splitstackshape)
setDT(mydf)[, CN := gsub("(.*?) ([0-9].*)", "\\1SPLIT\\2", column_name)] %>%
cSplit("CN", "SPLIT") %>%
cSplit("CN_2", "[y,]", "long", fixed = FALSE) %>%
cSplit("CN_2", "-") %>%
.[, list(values = list(if (is.na(CN_2_2)) CN_2_1 else CN_2_1:CN_2_2)),
.(CN_1, rowid(CN_1))] %>%
.[, list(values = list(unlist(values))), .(CN_1)]
# CN_1 values
# 1: akjhaa 1,2,3,4,5,6,...
# 2: bsd, 14,15,16,17,18,19,...
# 3: asdf asdf del 2,3,4,5,6
# 4: dkljwv 3,4,5,6,7,8,...
# 5: joikb 6, 7, 8, 9,10,11,...
# 6: sqwzsxcryvyde jd de 1,2
# 7: pk, ehde 1,2
# 8: jsd 1,2,3,4,5,6,...
# 9: asdasd asedd 1,3
Чтобы получить дополнительные столбцы вместо списка, вам понадобится еще одна строка: cbind(., .[, data.table::transpose(values)])
:
as.data.table(mydf)[, CN := gsub("(.*?) ([0-9].*)", "\\1SPLIT\\2", column_name)] %>%
cSplit("CN", "SPLIT") %>%
cSplit("CN_2", "[y,]", "long", fixed = FALSE) %>%
cSplit("CN_2", "-") %>%
.[, list(values = list(if (is.na(CN_2_2)) CN_2_1 else CN_2_1:CN_2_2)),
.(CN_1, rowid(CN_1))] %>%
.[, list(values = list(unlist(values))), .(CN_1)] %>%
cbind(., .[, data.table::transpose(values)])
Основная идея состоит в том, чтобы сделать следующие шаги:
- Разделить имена столбцов по значениям.
- Разделите значения, разделенные "y" или "," на новые строки.
- Разделите значения, разделенные "-", на несколько столбцов.
- Создайте свой список векторов в соответствии с правилом, что если какие-либо значения во втором столбце разделения
NA
вернуть только значение из первого столбца, в противном случае создайте последовательность от значения в первом столбце до значения во втором столбце. Поскольку вы продублировали значения "id", поскольку вы преобразовали данные в более длинную форму, используйтеrowid()
помочь с группировкой. - Консолидация значений в столбце списка в соответствии с фактическими идентификаторами.
- (Необязательно, на мой взгляд) преобразовать данные списка в несколько столбцов.