Обновите фрейм данных с другим в соответствующих строках, таких как SQL, обновите оператором соединения - PullRequest
2 голосов
/ 20 февраля 2020

Есть ли какой-нибудь простой способ обновить подмножество строк данных, используя другую?

Практически, я хочу использовать R, чтобы сделать UPDATE x INNER JOIN y ON x.col1 = y.col1 SET x.col2 = y.col2

Входные данные:

x <- data.frame(col1=c('a','c','b','d'), col2=c(11,34,13,25))

enter image description here

y <- data.frame(col1=c('a','b'), col2=c(3,5))

enter image description here

z <- match(x$col1,y$col1)

1 1 NA 2 NA

Выходы:

Метод 1

x$col2 <- y$col2[z]

enter image description here

Метод 2

x$col2[z] <- y$col2[z]

Ошибка в x $ col2 [z] <- y $ col2 [z]: NA не допускаются в назначениях с подпиской </p>

Метод 3

x$col2[z[!is.na(z)]] <- y$col2[z[!is.na(z)]]

enter image description here

Желаемый выход:

in x обновлять только те значения, которые соответствуют col1 из y

enter image description here

Ответы [ 2 ]

3 голосов
/ 20 февраля 2020

Поскольку в качестве операции, которую вы хотите использовать, используется соединение в стиле SQL, вам пригодится пакет sqldf:

library(sqldf)

sql <- "SELECT x.col1, COALESCE(y.col2, x.col2) AS col2
        FROM x LEFT JOIN y ON x.col1 = y.col1"
x <- sqldf(sql)

Данные:

x <- data.frame(col1=c('a','c','b','d'), col2=c(11,34,13,25))
y <- data.frame(col1=c('a','b'), col2=c(3,5))
1 голос
/ 20 февраля 2020

Вы можете использовать match в базе R:

x$col2[match(y$col1, x$col1)] <- y$col2
x

#  col1 col2
#1    a    3
#2    c   34
#3    b    5
#4    d   25

Или left_join и coalesce в dplyr

library(dplyr)

left_join(x, y, by = 'col1') %>%
  mutate(col2 = coalesce(col2.y, col2.x)) %>%
  select(names(x))

Наиболее эффективным будет присоединиться к обновлению data.table

library(data.table)

setDT(x)
setDT(y)
x[y, on=.(col1), col2:=i.col2]
...