我想在R中基于序列号,pnum和daynum的三列创建一个唯一的ID,以便它们创建一个唯一的人日ID。
我使用的是大型数据集,而do.call(interaction,df1)产生错误:无法分配大小为11.1gb的向量。
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
有什么建议吗?
答案 0 :(得分:1)
也许您正在追求哈希函数。
下面的代码将使用软件包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)
答案 1 :(得分:0)
您可以使用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))))
尝试一下,让我知道结果