Преобразовать строку в фрейме данных в вектор и развернуть фрейм данных

Дан фрейм данных, где каждое наблюдение в столбце является строкой вида "x ~ y", где x и y - целые числа.

Цель состоит в том, чтобы преобразовать строку "x ~ y" в вектор c (x..y), который представляет собой последовательность чисел, которые начинаются с целого числа x и заканчиваются целым числом y.

Наконец, фрейм данных должен быть анестирован, чтобы каждый элемент вектора получил свою собственную строку, а остальные столбцы были правильно повторены.

Например, вот кадр данных:

A     B
A1  -1~1
A2   1~3
A3   2~4

Вышеупомянутый фрейм данных должен быть изменен на следующее:

  A     B
    A1   -1
    A1    0
    A1    1
    A2    1
    A2    2
    A2    3
    A3    2
    A3    3
    A3    4

Невозможно установить примеры str_replace, так как есть много случаев.. Как мне сделать этот код??

1 ответ

Решение

Поскольку ваш столбец B может быть легко преобразован в выражение, которое дает вам то, что вы хотите, я бы использовал следующий подход.

# Using tidyverse for stringr (str_replace), tidyr (unnest), and purrr (map)
library(tidyverse)

# recreating your dataframe
df <- data.frame(A=c("A1","A2","A3"),B=c("-1~1","1~3","2~4"), stringsAsFactors = FALSE)

Это решение состоит из трех частей. Сначала преобразуйте строки в столбце B в выражения seq. Так что "x~y" становится "seq(x,y,by=1)".

df$B <- str_replace(df$B,"\\~",",")
df$B <- paste("seq(",df$B,",by=1)")

Одна из приятных вещей в R заключается в том, что если вы можете генерировать строки, содержащие выражения R, вы можете затем оценить их с помощью "eval(parse())", как это...

df$B <- map(df$B, ~ eval(parse(text=.)))

В качестве альтернативы вы могли бы вызвать функцию map(), которая бы взяла ваши исходные строки символов "x~y" и вернула бы нужный вам вектор целых чисел, но я думаю, что это решение имеет наименьшее количество типов (я думаю?).

Как бы вы это ни делали, теперь у вас есть столбец B, где каждое наблюдение представляет собой целочисленный вектор.

> df
   A        B
1 A1 -1, 0, 1
2 A2  1, 2, 3
3 A3  2, 3, 4

На последнем шаге разложите векторы в B, используя функцию tidyr, unnest. Это автоматически повторит значения столбца в строках по мере необходимости.

> df <- unnest(df)
> df
   A  B
1 A1 -1
2 A1  0
3 A1  1
4 A2  1
5 A2  2
6 A2  3
7 A3  2
8 A3  3
9 A3  4
Другие вопросы по тегам