Замена определенных значений в data.frame в R - PullRequest
0 голосов
/ 21 декабря 2011

Я пытаюсь заменить НС в «тесте» прогнозными значениями в «прогнозе».Я пытаюсь использовать матч, но я не могу понять это.имейте в виду, что идентификатор и время создают уникальный идентификатор из двух частей.Какие-либо предложения?(имейте в виду, что мой набор данных намного больше, чем в этом примере (строки = 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))

Ответы [ 3 ]

2 голосов
/ 22 декабря 2011

Вот решение 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)]

EDIT. Сравнительные тесты: таблица данных в 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
1 голос
/ 21 декабря 2011

Я бы использовал 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
0 голосов
/ 21 декабря 2011

Попробуйте это:

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