Ошибка размера памяти при создании уникального идентификатора с использованием 3 столбцов - PullRequest
0 голосов
/ 31 декабря 2018

Я хочу создать уникальный идентификатор в R на основе трех столбцов serial, pnum и daynum, чтобы они создавали уникальный идентификатор person-day.

Я использую большой набор данных и do.call(взаимодействие, df1) выдает ошибку: не может выделить вектор размером 11,1 ГБ.

serial         pnum daynum
11011202        1   1
11011202        1   2
11011202        4   1
11011202        4   2
11011203        1   1
11011203        1   2
11011207        1   1
11011207        1   2
11011207        2   1
11011207        2   2
11011209        1   1
11011209        1   2
11011209        2   1
11011209        2   2

Любое предложение, пожалуйста?

Ответы [ 2 ]

0 голосов
/ 31 декабря 2018

вы можете сделать это с помощью Base R.Это не займет много вашего ОЗУ

data1 <- read.table(text="serial         pnum daynum
11011202        1   1
11011202        1   2
11011202        4   1
11011202        4   2
11011203        1   1
11011203        1   2
11011207        1   1
11011207        1   2
11011207        2   1
11011207        2   2
11011209        1   1
11011209        1   2
11011209        2   1
11011209        2   2",header = T)


data1$id <- as.integer(factor(with(data1, paste(serial, pnum,daynum))))

попробуйте это и дайте мне знать результат

0 голосов
/ 31 декабря 2018

Возможно, вам нужна хеш-функция.
В приведенном ниже коде будет использоваться пакет hashFunction.Он имеет 3 различные хеш-функции, которые я тестировал с murmur3.32, который генерирует 32-битные хеш-функции

Сначала приведен пример использования с данными в вопросе ..

library(hashFunction)

apply(df1, 1, function(x) murmur3.32(paste(x, collapse = "")))

Теперь увеличен набор данных.

serial <- rep(11011200 + 1:1000000, each = 4)
n <- length(serial)
pnum = rep(rep(1:2, each = 2), length.out = n)
daynum <- rep(1:2, length.out = n)

df2 <- data.frame(serial, pnum, daynum)
sum(duplicated(df2))
#[1] 0

Тесты с большим df2.Время доступа к матрице быстрее, чем для df, поэтому я принудительно df2 к матрице ..

system.time({
  h <- apply(as.matrix(df2), 1, function(x) murmur3.32(paste(x, collapse = "")))
})
#     user    system   elapsed
#   74.199     0.059    74.289

Теперь попробуйте сначала зарезервировать память и назначить значения в цикле for.

system.time({
  h2 <- integer(n)
  tmp <- as.matrix(df2)
  for(i in seq_len(n)) 
    h2[i] <- murmur3.32(paste(tmp[i, ], collapse = ""))
  rm(tmp)
})
#     user    system   elapsed
#   67.321     0.045    67.406 

identical(h, h2)
#[1] TRUE

object.size(df2)
#64000984 bytes

object.size(h)
#16000048 bytes

Вектор хеш-функции в 4 раза меньше, чем кадр данных.

Данные.

df1 <- read.table(text = "
serial         pnum daynum
11011202        1   1
11011202        1   2
11011202        4   1
11011202        4   2
11011203        1   1
11011203        1   2
11011207        1   1
11011207        1   2
11011207        2   1
11011207        2   2
11011209        1   1
11011209        1   2
11011209        2   1
11011209        2   2                  
", header = TRUE)
...