我有 data1 和 data2 ,我需要 data3 ,用<替换 data1 的某些区域EM> DATA2
我使用此方法更新数据,但实际上需要更新几个列,这将是繁琐的。
你知道更简单的方法吗?
library(tidyverse)
library(lubridate)
data1 <- tibble(date=date("2017-11-1") + c(1:10),
a=sample(100,10),b=sample(100,10))
data2 <- tibble(date=date("2017-11-1") + c(1:8),
a=sample(100,8))
data_bind <- left_join(data1, data2, by=("date"))
data_bind$a.x[!is.na(data_bind$a.y)] <- data_bind$a.y[!is.na(data_bind$a.y)]
data_bind %>% select(-a.y) %>% dplyr::rename(a=a.x)
答案 0 :(得分:5)
在我看来,data.table
- 包更适合这样的任务。使用:
# create a vector with names from 'data2' that are not used to join by
nms <- names(data2)[-1]
# load the 'data.table'-package
library(data.table)
# convert the dataframes to data,table's
setDT(data1)
setDT(data2)
# join and update the column in 'data1' with the matching values from 'data2'
data1[data2, on = 'date', (nms) := mget(paste0('i.',nms))][]
给出:
date a b 1: 2017-11-02 21 11 2: 2017-11-03 22 12 3: 2017-11-04 23 13 4: 2017-11-05 24 14 5: 2017-11-06 25 15 6: 2017-11-07 26 16 7: 2017-11-08 27 17 8: 2017-11-09 28 18 9: 2017-11-10 9 19 10: 2017-11-11 10 20
这是做什么的:
setDT(data1)
将dataframes / tibbles转换为data.table。data1[data2, on = 'date']
,您可以加入data.table-way。(nms) := mget(paste0('i.',nms))
,您告诉data.table
更新data1
中的列,其中的列仅在日期匹配的data2
中出现。 作为替代方法,您还可以将两个数据集重新整形为长格式,然后进行连接:
library(data.table)
melt(data1, id = 'date')[melt(data2, id = 'date')
, on = .(date, variable)
, value := i.value
][, dcast(.SD, date ~ variable)]
将此方法转换为tidyverse
:
library(dplyr)
library(tidyr)
gather(data1, key, value, -1) %>%
left_join(., gather(data2, key, value, -1), by = c('date','key')) %>%
mutate(value.x = ifelse(!is.na(value.y), value.y, value.x)) %>%
select(date, key, value = value.x) %>%
spread(key, value)
两者都会给你相同的输出。
使用过的数据:
data1 <- data.frame(date = as.Date("2017-11-1") + c(1:10), a = 1:10, b = 11:20)
data2 <- data.frame(date = as.Date("2017-11-1") + c(1:8), a = 21:28)