Я пытаюсь просмотреть таблицу data.table по группам, чтобы присвоить значение каждой строке условно внутри каждой подгруппы. Я могу выбрать нужные строки, но не могу обновить интересующую переменную в выбранных строках.
Я думаю, это может быть связано с тем, что мне нужно дважды нарезать таблицу данных. Я работаю с data.table
с именем dt
, в котором есть столбцы group
, center
, date
и var
. Здесь цель состоит в том, чтобы сопоставить значение var
нецентральных записей, то есть center==0
, с их ближайшими (с точки зрения разницы дат) центральными записями, где center==1
. Предположим, i
- это позиционный индекс строки, и я хочу обновить запись на основе условной фильтрации, а затем выполнить поиск по date
в подгруппе gp
.
dt[group == gp][i, var:= "new value"]
Но когда я бегу
dt[group == gp][i, var]
Переменная var
кажется неизменной, иначе возвращает "old value"
.
Дополнительная информация
Вышеприведенная команда находится внутри цикла for, возможно, я здесь не использую лучшие практики. Буду признателен, если кто-то поделится своим мнением по поводу следующего цикла for. Спасибо.
for( gp in unique(dt$group)){
tmp = dt[group==gp]
for( i in 1:nrow(tmp)){
new_val = tmp[center==1][which.min(abs(tmp[i, date]-tmp[center==1, date]),var]
dt[group == gp][i, var:= new_val]
}
}
Мне известно о set
и .by
в data.table. Но я не знаю, как легко применить условную функцию поиска к каждой подгруппе с синтаксисом dt[, j=somefunction ,by=group]
. Может быть, я мог бы поставить saply на .SD
, но намного ли он быстрее, чем цикл for? Означает ли выигрыш в производительности потерю читабельности?
Редактировать
В разделе комментариев ниже я нашел способ комбинировать логическую и позиционную индексацию в data.table одновременно:
dt[which(group == gp)[i], var := new_val]
Вопрос о том, является ли использование цикла for хорошей идеей, до сих пор остается без ответа. Любые вклады будут оценены!
* * Пример тысячи сорок четыре * * 1045
Предположим, что исходный dt (отсортированный по группе и дате) выглядит следующим образом:
group center date var
1 0 10-01 NA
1 1 10-02 val1
1 0 10-03 NA
1 1 11-05 val2
2 1 10-02 val3
Я хочу, чтобы обновленный dt был:
group center date var
1 0 10-01 val1
1 1 10-02 val1
1 0 10-03 val1
1 1 11-05 val2
2 1 10-02 val3
Допустим, у нас здесь около 10 000 групп, и в каждой группе может быть до 1000 строк.