是否可以使用比使用因子更小的数据集?

Jra*_*u56 3 r dataframe

我试图减少我的一些数据集的内存占用,其中每列有一小部分因子(重复很多次).有没有更好的方法来减少它?为了比较,这是我从使用因素得到的:

library(pryr)

N <- 10 * 8
M <- 10
Run Code Online (Sandbox Code Playgroud)

初步数据:

test <- data.frame(A = c(rep(strrep("A", M), N), rep(strrep("B", N), N)))
object_size(test)
# 1.95 kB
Run Code Online (Sandbox Code Playgroud)

使用因素:

test2 <- as.factor(test$A)
object_size(test2)
# 1.33 kB
Run Code Online (Sandbox Code Playgroud)

旁白:我天真地认为他们用一个数字取代了弦乐,并且看到test2小于的数字令人惊喜test3.谁能指点我如何优化因子表示?

test3 <- data.frame(A = c(rep("1", N), rep("2", N)))
object_size(test3)
# 1.82 kB
Run Code Online (Sandbox Code Playgroud)

Emi*_*ode 8

我担心差异很小.

原理很简单:代替(在你的例子中)160个字符串,你只需要存储2个,以及160个整数(只有4个字节).
除了R类存储字符内部相同的方式.

每种现代语言都支持(几乎)无限长度的字符串.这就产生了一个问题,即您不能将字符串的向量(或数组)存储为一个连续的块,因为任何元素都可以重置为任意长度.因此,如果将另一个值分配给一个元素,这个值恰好要长一些,那就意味着必须移动数组的其余部分.或OS /语言应为每个字符串保留大量空间.
因此,字符串存储在内存中的任何位置都很方便,并且数组(或R中的向量)被存储为指向实际值的位置的指针块.
在R的早期,每个指针指向内存中的另一个位置,即使实际值相同.所以在你的例子中,160个指针指向160个内存位置.但是这已经改变了,现在它被实现为160个指向2个内存位置的指针.可能存在一些小的差异,主要是因为一个因子通常只能支持2 ^ 31-1个级别,这意味着32位整数足以存储它,而一个字符大多使用64位指针.然后,因素中有更多的开销.
一般来说,如果你真的有很大的重复百分比,使用因子可能会有一些优势,但如果不是这样,它甚至可能会损害你的内存使用量.

您提供的示例不起作用,因为您将data.frame与因子进行比较,而不是使用裸字符.
更强大的:当我复制你的榜样,我只得到你的结果,如果我设置stringsAsFactorsFALSE,让你在一个data.frame的因素比较的一个因素.
比较结果否则会产生很小的差异:角色为1568,因子为1328.
只有当你有很多相同的值时,这才有效,如果你看这个,你会看到因子可以更大:

> object.size(factor(sample(letters)))
2224 bytes
> object.size(sample(letters))
1712 bytes
Run Code Online (Sandbox Code Playgroud)

因此,通常情况下,没有真正的方法来压缩数据,同时仍然保持易于使用,除了在您实际想要存储的内容中使用常识.