Как заменить определенное значение в одной таблице data.table значениями другой таблицы data.table той же размерности

Учитывая две таблицы data.table:

dt1 <- data.table(id = c(1,-99,2,2,-99), a = c(2,1,-99,-99,3), b = c(5,3,3,2,5), c = c(-99,-99,-99,2,5))
dt2 <- data.table(id = c(2,3,1,4,3),a = c(6,4,3,2,6), b = c(3,7,8,8,3), c = c(2,2,4,3,2))

> dt1
    id   a b   c
1:   1   2 5 -99
2: -99   1 3 -99
3:   2 -99 3 -99
4:   2 -99 2   2
5: -99   3 5   5

> dt2
   id a b c
1:  2 6 3 2
2:  3 4 7 2
3:  1 3 8 4
4:  4 2 8 3
5:  3 6 3 2

Как можно заменить -99 в dt1 на значения dt2?

Желаемый результат должен быть dt3:

> dt3
   id a b c
1:  1 2 5 2
2:  3 1 3 2
3:  2 3 3 4
4:  2 2 2 2
5:  3 3 5 5

Возможный дубликат Условное слияние / замена в R

patL 07.05.2018 12:46
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
90
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Это должно сработать, простой подход:

  for (i in 1:nrow(dt1)){
    for (j in 1:ncol(dt1)){
    if (dt1[i,j] == -99) dt1[i,j] = dt2[i,j]
    }
    }
Ответ принят как подходящий

Вы можете сделать следующее:

dt3 <- as.data.frame(dt1)
dt2 <- as.data.frame(dt2)
dt3[dt3 == -99] <- dt2[dt3 == -99]
dt3

#   id a b c
# 1  1 2 5 2
# 2  3 1 3 2
# 3  2 3 3 4
# 4  2 2 2 2
# 5  3 3 5 5

Если все ваши данные одного типа (как в вашем примере), то преобразование их в matrix будет намного быстрее и прозрачнее:

dt1a <- as.matrix(dt1)  ## convert to matrix
dt2a <- as.matrix(dt2)

# make a matrix of the same shape to access the right entries
missing_idx <- dt1a == -99  
dt1a[missing_idx] <- dt2a[missing_idx]  ## replace by reference

Это векторизованная операция, поэтому она должна быть быстрой.

Примечание: Если вы это сделаете, убедитесь, что два источника данных точно совпадают по форме и порядку строк / столбцов. Если они этого не делают, вам нужно присоединиться с помощью соответствующих ключей и выбрать правильные столбцы.

Обновлено: Преобразование в матрицу может быть ненужным. См. Ответ kath для более краткого решения.

Этот простой трюк сработает эффективно.

dt1<-as.matrix(dt1)
dt2<-as.matrix(dt2)

index.replace = dt1==-99
dt1[index.replace] = dt2[index.replace]

as.data.table(dt1)
as.data.table(dt2)

Простым способом может быть использование функции setDF для преобразования в data.frame и использование методов подустановки фрейма данных. В конце восстановите на data.table.

#Change to data.frmae
setDF(dt1)
setDF(dt2)

# Perform assignment 
dt1[dt1==-99] = dt2[dt1==-99]

# Restore back to data.table    
setDT(dt1)
setDT(dt2)

dt1
#   id a b c
# 1  1 2 5 2
# 2  3 1 3 2
# 3  2 3 3 4
# 4  2 2 2 2
# 5  3 3 5 5

Другие вопросы по теме