【问题标题】:Replacing certain values in data.frame in R替换R中data.frame中的某些值
【发布时间】:2011-12-22 04:12:26
【问题描述】:

我正在尝试用“预测”中的预测值替换“测试”中的 NA。我正在尝试使用匹配,但我无法弄清楚。请记住 id 和 time 创建一个由两部分组成的唯一 id。有什么建议么? (请记住,我的数据集比这个例子大得多(rows=32000))

test = data.frame(id =c(1,1,1,2,2,2), time=c(89,99,109,89,99,109), data=c(3,4,NA,5,2,NA))
forecast = data.frame(id =c(1,2), time=c(109,109), data=c(5,1))

期望的输出

out = data.frame(id =c(1,1,1,2,2,2), time=c(89,99,109,89,99,109), data=c(3,4,5,5,2,1))

【问题讨论】:

  • 是每个 NA 值都被替换为预测值,还是在输出中会保留一些 NA?

标签: r replace match


【解决方案1】:

这里是data.table 解决方案

test_dt <- data.table(test, key = c('id', 'time'))
forecast_dt <- data.table(test, key = c('id', 'time'))
forecast[test][,data := ifelse(is.na(data), data.1, data)]

编辑。基准测试:即使对于小型数据集,数据表也快 3 倍。

库(rbenchmark)

f_merge <- function(){
  out2 <- merge(test, forecast, by = c("id", "time"), all.x = TRUE)
  out2 <- transform(out2, 
   newdata = ifelse(is.na(data.x), data.y, data.x), data.x = NULL, data.y = NULL)
  return(out2)
}

f_dtable <- function(){
  test <- data.table(test, key = c('id', 'time'))
  forecast <- data.table(forecast, key = c('id', 'time'))
  test <- forecast[test][,data := ifelse(is.na(data), data.1, data)]
  test$data.1 <- NULL
  return(test)
}

benchmark(f_merge(), f_dtable(), order = 'relative', 
  columns = c('test', 'elapsed', 'relative'))

        test elapsed relative
2 f_dtable()    0.86     1.00
1  f_merge()    2.26     2.63

【讨论】:

    【解决方案2】:

    我会使用merge 将数据连接在一起,然后分两步计算您的新列:

    out2 <- merge(test, forecast, by = c("id", "time"), all.x = TRUE)
    > out2
      id time data.x data.y
    1  1   89      3     NA
    2  1   99      4     NA
    3  1  109     NA      5
    4  2   89      5     NA
    5  2   99      2     NA
    6  2  109     NA      1
    
    #Compute new variable and clean up old ones:
    
    out2 <- transform(out2, newdata = ifelse(is.na(data.x), data.y, data.x), data.x = NULL, data.y = NULL)
    > out2
      id time newdata
    1  1   89       3
    2  1   99       4
    3  1  109       5
    4  2   89       5
    5  2   99       2
    6  2  109       1
    

    【讨论】:

    • 我在上面发表评论的原因是,我将建议简单地删除带有 NAs 的行,然后 rbinding 预测值打开,但假设每个缺失值都在预测中.
    • @Joran - 这将是偷偷摸摸的和快速的。我喜欢。 merge 可能会因为很多行而变慢,所以我也打算将等效的 data.table() 答案放在一起,但我敢打赌你提出的解决方案仍然是最快的。
    【解决方案3】:

    试试这个:

    test$data[is.na(test$data)] <- forecast[((forecast$id %in% test$id) & (forecast$time %in% test$time)),]$data
    

    【讨论】:

    • 抱歉,这行不通。我最初并没有指定我的数据集非常大......所以不能手动做任何事情。
    • 我的代码将为您提供与您想要的输出(输出)相同的结果。我认为您必须编辑您的问题以提供一些建议您要解决的问题是什么
    • 它解决了 立即 问题,但对其他选项的可扩展性或灵活性不高。这相当于edit(test) 并手动更改内容...非常适合 6 行数据,对于 6000 行真的很糟糕。
    • 仅当testforecast 先按id 和时间排序。您还对是否正在预测每个缺失值做出假设,或者只预测一些。
    • 我用他提供的数据回答了这个问题。我无法处理数据中可能存在的所有特殊性。
    猜你喜欢
    • 2022-09-27
    • 2021-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多