Как динамически создавать переменные цикла и str_replace в R

#r

#r

Вопрос:

Я пытаюсь проанализировать несколько столбцов в каждом из их компонентов. Однако количество компонентов варьируется в зависимости от столбцов. В частности, предположим, что следующий df:

 id  X1.startAll                                        X2.startAll          
1   ["1555726884484","1555727530298","1555727532509"]  
2                                                      ["1555735159384","1555735161545"]
3   ["1555730029709"]
4   ["1555735159384","1555735161545"]
5
6                                                      ["1555735159384","1555735161545"]
  

теперь у меня есть 40 таких столбцов (и еще 120 очень похожих, на которые я стремлюсь обобщить процесс) и еще много строк. Я могу сделать первый столбец довольно просто, используя следующее:

 df1$X1.startAll1 <- str_replace(df1$X1.startAll, "\["([0-9] )",*"*([0-9]*)"*,*"*([0-9]*)"*\]", "\1")

df1$X1.startAll2 <- str_replace(df1$X1.startAll, "\["([0-9] )",*"*([0-9]*)"*,*"*([0-9]*)"*\]", "\2")

df1$X1.startAll3 <- str_replace(df1$X1.startAll, "\["([0-9] )",*"*([0-9]*)"*,*"*([0-9]*)"*\]", "\3")
  

что дает желаемый результат:

 id  X1.startAll                                        X1.startAll1    X1.startAll2   X1.startAll3    
1   ["1555726884484","1555727530298","1555727532509"]  1555726884484   1555727530298  1555727532509
2                                                      
3   ["1555730029709"]                                  1555730029709
4   ["1555735159384","1555735161545"]                  1555735159384   1555735161545
5
6                                                      
  

Однако я должен сделать это для многих столбцов и для многих разных длин «массива» в каждом из них.

Я пытался автоматизировать это с помощью цикла for, однако я (1) не могу понять, как прочитать нужное количество итераций (т. Е. Максимальное количество компонентов в столбце startAll), (2) динамически создавать переменные, (3) ни как динамически обновлять извлечение строки («\ i»).

Любая помощь по циклированию этого процесса очень помогла бы!

Редактировать 2: ниже приведен образец данных, который можно скопировать и вставить:

 structure(list(X1.startAll = list(NA, NA, NA, NA, c(1555726884484, 
1555727530298, 1555727532509), NA, NA, c(1555735159384, 1555735161545
), NA, NA, NA, 1555730029709, NA, NA, NA, c(1555728423843, 1555728561054, 
1555728586917), c(1555725657389, 1555725657827), c(1555703810672, 
1555703823206, 1555703848659), NA, NA), X2.startAll = list(NA, 
    NA, NA, NA, c(1555727541885, 1555727786959, 1555727897893
    ), NA, NA, 1555735262052, c(1555737694350, 1555737696711), 
    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), X3.startAll = list(
    NA, NA, NA, NA, c(1555727920770, 1555728230065, 1555728843391
    ), NA, NA, c(1555735331144, 1555735452321, 1555735457305), 
    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), X4.startAll = list(
    NA, NA, NA, NA, 1555728854666, NA, NA, 1555735589629, 1555738374484, 
    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), X5.startAll = list(
    NA, NA, NA, NA, c(1555728949327, 1555728988444), NA, NA, 
    c(1555735646258, 1555735912372, 1555735914267, 1555736071856, 
    1555736074184, 1555736093411, 1555736124826, 1555736238538, 
    1555736248889, 1555736576754, 1555736620915, 1555736874386, 
    1555737698921, 1555737777400, 1555737966562, 1555738152090, 
    1555738354075, 1555738700232, 1555738703134, 1555738716736
    ), 1555738415269, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
    NA), X6.startAll = list(NA, NA, NA, NA, 1555729661240, NA, 
    NA, NA, 1555738960285, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
    NA, NA), X7.startAll = list(NA, NA, NA, NA, c(1555730266934, 
1555730356654, 1555730533798, 1555730535289), NA, c(1555732523945, 
1555733415340, 1555733477452, 1555733748200, 1555734007271, 1555734286685, 
1555734288597), NA, c(1555739871726, 1555740315324, 1555740328252, 
1555740329835, 1555740538272, 1555741140561, 1555741143555, 1555741152932
), c(1555743562826, 1555743566386, 1555743593201), NA, NA, NA, 
    c(1555727969354, 1555727985539, 1555728064237, 1555738166838, 
    1555826735910), NA, NA, NA, NA, NA, NA), X8.startAll = list(
    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
    NA, NA, NA, NA, NA)), row.names = c(NA, -20L), class = "data.frame")
  

Комментарии:

1. Выглядит как json. Возможно, было бы проще использовать пакет синтаксического анализа json в вашем рабочем процессе.

2. Если вам нужна помощь оттуда, где вы находитесь, было бы неплохо, если бы вы предоставили входные данные в формате копирования / вставки, dput(df) (или dput(droplevels(head(df))) если у вас есть factor столбцы и больше строк)

3. Привет @Gregor, все эти массивы я создал на javascript и на самом деле раньше не использовал пакет синтаксического анализа json, но звучит интересно. Я просто быстро взглянул на jsonlite и попытался использовать flatten , но массивы в этих столбцах сами по себе не являются фреймами данных. Я обновил вопрос, чтобы включить версию для копирования и вставки! Большое спасибо.

4. У вас нет полного ответа (и вам нужно выполнить работу), но для начала определите my_parser = function(x) {if (x == "") return(NA); as.numeric(jsonlite::fromJSON(txt = x))} , а затем df[] = lapply(df, lapply, parser) дайте довольно хороший старт. Помещает числовые векторы вместо строк json в каждый столбец, просто нужно отделить их оттуда.

5. О, забыл один шаг. Ошибка заключается в том, что вы начинаете с факторов, а не символов. Сначала сделайте это: df[] = lapply(df, as.character) и мой код будет запущен. (Это, вероятно, поможет и с другими методами.)