从新数据框更新旧列条目

时间:2018-02-22 00:48:03

标签: r dataframe merge

我正在解决一个问题。以下是原始60k行数据帧的概念。

dataOne <- data.frame(
    marketVal = c(NA, 543534, NA, 115435, NA),
    bathrooms = c(3,3,2,3,5),
    garageSqFt = c(400, 385, 454, 534, 210),
    totalSqFT = c(NA, NA, 1231, 2232, 4564),
    units = c(1, 1, 1, 1, 1),
    subDivId = c("112", "111", "111", "111", "112"),
    ID = c(4,56,67,94,130) )

市场价值的一些NA已被检索并存储在新的中 看起来像这样的数据框:

dataTwo <- data.frame(
    marketVal = c(123123,234234),
    IDTwo = c(4,67) )
str(dataTwo)
dataOne$marketVal <- dataTwo$marketVal[match(dataTwo$ID, dataOne$ID)]

比较两个数据帧中的ID我试图将第一个数据帧中的NA替换为第二个数据帧中的市场值。我已经尝试了匹配功能如下:

dataOne$marketValue <- dataTwo$marketValue[match(dataOne$ID, dataTwo$ID)]

但收到错误“替换有2行,数据有5个调用”。我觉得这两个数据框大小不一样的事实并不重要,因为我们只比较两者中的ID。考虑到大约4500 NA需要更新,我怎样才能有效地实现这一目标?

3 个答案:

答案 0 :(得分:0)

您的方法无效,因为它正在生成一个包含5个值的向量:next_day,它比1 NA 2 NA NA数据帧长。删除NA值,您的方法将起作用。

我就是这样做的:

dataTwo

(请注意,您提供的示例中,rowMatch <- which(dataOne$ID %in% dataTwo$ID) dataOne[rowMatch, ]$marketVal <- dataTwo$marketVal 个变量实际上分别为IDIDOne。)

答案 1 :(得分:0)

您可以使用merge

require(tidyverse)    
new <- merge(dataOne, dataTwo, by.x = 'ID', by.y = 'IDTwo', all.x = T) 
new$marketVal <- new %$% coalesce(marketVal.x, marketVal.y)

答案 2 :(得分:0)

我们可以使用我的软件包safejoin中的safe_left_join,并进行“补丁” 列冲突时,从rhs到lhs的匹配。

# devtools::install_github("moodymudskipper/safejoin")
library(safejoin)
library(dplyr)

dataOne <- data.frame(
  marketVal = c(NA, 543534, NA, 115435, NA),
  bathrooms = c(3,3,2,3,5),
  garageSqFt = c(400, 385, 454, 534, 210),
  totalSqFT = c(NA, NA, 1231, 2232, 4564),
  units = c(1, 1, 1, 1, 1),
  subDivId = c("112", "111", "111", "111", "112"),
  ID = c(4,56,67,94,130) )

dataTwo <- data.frame(
    marketVal = c(123123,234234),
    IDTwo = c(4,67) )

safe_left_join(dataOne, dataTwo, by=c(ID= "IDTwo"), conflict = "patch")
#   marketVal bathrooms garageSqFt totalSqFT units subDivId  ID
# 1    123123         3        400        NA     1      112   4
# 2    543534         3        385        NA     1      111  56
# 3    234234         2        454      1231     1      111  67
# 4    115435         3        534      2232     1      111  94
# 5        NA         5        210      4564     1      112 130

或者在这种情况下,为了达到相同的效果,我们可以使用dplyr::coalesce

library(dplyr)
safe_left_join(dataOne, dataTwo, by=c(ID= "IDTwo"), conflict = coalesce)