Почему эта команда работает, когда она написана от руки, а не тогда, когда те же входные данные взяты из таблицы data.table? - PullRequest
1 голос
/ 22 марта 2020

Сводка: У меня есть две строки кода, которые используют data.table и rbind, чтобы взять произвольный список строк из одной таблицы, добавить их в другую таблицу, а затем удалить эти строки из исходной таблицы. Я пытаюсь заставить это работать, рисуя эти входные данные (исходная таблица, таблица назначения, список строк) из столбцов третьей таблицы. IE вместо (пример псевдокода) table1<-rbind(table1, table2[list_of_rownums_to_copy]) Я хочу, чтобы оно работало чисто как table3$col1<-rbind(table3$col1, table3$col2[table3$col4]), где каждая строка col1 и col2 содержит имена других таблиц, а col4 содержит списки округленных чисел. Таким образом, я могу обернуть команды в функцию и автоматизировать ее запуск несколько раз, используя mapply или аналогичный.

Подробно: Для целей тестирования я создал таблицы dtA через DTF. Все они имеют одинаковый формат с разным количеством строк в таблице. Для пробела здесь есть первые 6 строк только таблицы dtA. Другие таблицы те же, у них просто есть буква в столбце «orig_table» вместо «a»:

     val     orig_table ##dtA has "a" in this column, dtB has "b", etc
1     1          a
2     2          a
3     3          a
4     4          a
5     5          a
6     6          a

Следующие две строки кода отлично работают на любых двух выбранных таблицах, пока я сдаю -записать все в и дать объект списка:

dtA<- rbind(dtA, dtB[list_of_row_numbers, ])
dtB<- dtB[ -list_of_row_numbers, ]   

В этом случае dtA является таблицей назначения, dtB является таблицей происхождения, а list_of_row_numbers является объектом списка, содержащим случайные числа, которые принимаются за номер строки, для которой выбираются строки. IE список c(1, 3, 5) добавит строки 1, 3, 5 из таблицы dtB в таблицу dtA. Вторая строка использует тот же список, чтобы определить, какие строки следует удалить из dtB впоследствии. По сути, это то же самое, что «вырезать и вставить».

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

    V1     V2    V3            V4
1: dtA    dtB   5804    3500,44228,22805,47866,32495,69006,...
2: dtA    dtC   5637    59773,55783,73482,84333,57466,88604,...
3: dtA    dtD   7292    67684,90789,67507,32937,90235,83391,...
4: dtA    dtE   3321    16810,12906,40822,40316,52624,85656,...
5: dtA    dtF   4268    89944,22578,23585,95320,79005,63923,...
6: dtB    dtA   3219    46716,54828,11475,29245,76940, 2535,...

Содержание первой строки соответствует примеру, который я привел для рукописной команды. Строка 1 столбца V1 - это таблица назначения (dtA), строка 1 столбца V2 - исходная таблица (dtB), а строка 1 столбца V4 - список строк, над которыми нужно работать:

 V1          V1   V2      V4
dtA<- rbind(dtA, dtB[list_of_row_numbers, ]) ## this copies rows from dtB to dtA
dtB<- dtB[ -list_of_row_numbers, ]   ## this deletes them from dtB afterwards

I'm пытаясь получить это, чтобы принять ввод непосредственно из таблицы dt1. Конечная цель заключает в себе эти две строки в функции для использования с mapply, чтобы выполнить итерацию по всей таблице dt1, выполняя каждую операцию с входными данными, перечисленными в каждой строке.

Проблема в том, что я не могу понять синтаксис, чтобы сделать это. Я попытался просто ввести dt1$V1 вместо dtA, как показано ниже, но это не сработало совсем:

dt1$V1<- rbind(dt1$V1, dt1$V2[dt1[,V4])
dt1$V2<- dt1$V2[ -dt1[,V4], ]

Я решил подобную проблему раньше, заключив вход в eval(as.name(dt1$V1)), что получил другую команду, чтобы правильно интерпретировать row1 col1 как имя объекта, а не просто текст, но здесь это не работает.

1 Ответ

1 голос
/ 22 марта 2020

Мы могли бы l oop по строкам и assign объектам в каждой строке по rbinding набору данных с объектами из столбца 'V2'

for(i in seq_len(nrow(dt1))) {

   assign(dt1$V1[i], rbind(get(dt1$V1[i]), get(dt1$V2[i])[dt1$V4[[i]],])) 
   assign(dt1$V2[i], get(dt1$V2[i])[-dt1$V4[[i]],])
 }

Столбцы ' V1 ',' V2 'имеют имена объектов, хранящиеся в виде строки. Чтобы обновить эти объекты в глобальном окружении, нам нужно assign объекты к новому значению. Например,

v1 <- 5
assign("v1", 10)
v1
#[1] 10

Кроме того, поскольку имена объектов являются строками, чтобы вернуть значение из этой строки, мы используем get

get("v1")
#[1] 10

В l oop мы динамически используя assign и get для обновления этих объектов в глобальном env на каждой итерации

...