用新数据替换部分数据框

标签 r dplyr

我有data1data2,并且我需要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)

最佳答案

在我看来,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),您可以将数据帧/标题转换为data.table。
  • 使用data1[data2, on = 'date'],您可以进行 data.table-way 连接。
  • 通过将 (nms) := mget(paste0('i.',nms)) 添加到连接,您可以告诉 data.table 更新data1 中的列也仅在日期匹配的情况下才出现在 data2 中。

作为替代方法,您还可以将两个数据集 reshape 为长格式,然后进行连接:

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)

关于用新数据替换部分数据框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47588455/

相关文章:

使用 dplyr 从另一列返回值

r - 如何创建一个函数来获取汇总统计数据作为列?

r - 通过R中的方式组合具有重复ID的行

r - 如何获取 enframe 内的名称

r - 如何为分类数据创建 'clustered dotplots'?

r - 使用 R/plotly 在轴标题中写入符号摄氏度

r - 将列添加到 R 中数据帧的数据帧列表中的特定行

r - 如何在 dplyr 中使用切片来保留 R 中具有 NA 值的行

r - R 中的合并表

r - 获取组中3个最常见的元素,连接关系并忽略不太常见的值