R split()函数大小增加问题

时间:2015-03-19 05:39:43

标签: r memory text-processing categorical-data logfile-analysis

我有以下数据集

> head(data)
  X    UserID NPS V3 V4 V5                                   Event              V7          Element                            ElementValue 
1 1 254727216  10  0 19 10 nps.agent.14b.no other attempt was made 10/4/2014 23:59 cea.element_name nps.agent.14b.no other attempt was made
2 2 298379949   0  0 28 11 nps.agent.14b.no other attempt was made 9/30/2014 23:59 cea.element_name nps.agent.14b.no other attempt was made
3 3 254710917   0  0 20 12 nps.agent.14b.no other attempt was made 9/15/2014 23:59 cea.element_name nps.agent.14b.no other attempt was made
4 4 238919392   7  0 17  9 nps.agent.14b.no other attempt was made 9/17/2014 23:59 cea.element_name nps.agent.14b.no other attempt was made
5 5 144693025  10  0 18 10 nps.agent.14b.no other attempt was made 9/17/2014 23:59 cea.element_name nps.agent.14b.no other attempt was made
6 6 249978568   5  0 21 12 nps.agent.14b.no other attempt was made 9/18/2014 23:59 cea.element_name nps.agent.14b.no other attempt was made

当我将数据集拆分为:

data_splitted <- split(data,data$UserID)

这里的问题是当我用整个数据集而不是这个样本尝试这个时,大小超出我的ram的大幅增加

> format(object.size(data),units="Mb")
[1] "0.2 Mb"
> format(object.size(data_splitted),units="Mb")
[1] "45.7 Mb"

关于为什么会发生这种情况以及是否有任何解决方法的任何见解都将受到赞赏。

2 个答案:

答案 0 :(得分:3)

试试这个:

data$UserID <- as.character(data$UserID)
data_splitted <- split(data,data$UserID)

在你的情况下发生的事情是因为ID是数字的,所以这个数字被用作创建列表中的索引(位置),这显然是不对的。由于id的数量非常高,因此R填充了空白列表(因此对象大小很大)。通过使id成为字符变量,我们避免这种情况。

另一种将id变量保留在1行数据帧内的方法是:

data_splitted <- list()
for(i in 1:nrow(data))
  data_splitted[[as.character(data$UserID[i])]] <- data[i,]

要访问新创建的列表中的元素,如果您使用$运算符,则需要引用这些数字:

data_splitted$"144693025"
data_splitter[["144693025"]]

另一个选项是在数字ID前面添加字符。例如:

data$UserID <- paste0("id",data$UserID)
data_splitted <- split(data,data$UserID)

这使得访问列表项更方便:

data_splitted$id144693025
data_splitted$id238919392

答案 1 :(得分:1)

如果您有许多类似的字符串,请使用因子而不是字符串。 (如果你不需要处理他们的内容,根本不要存储它们,或者只存储例如主机名,作为因素。你可以使用grep和正则表达式进行捕获 - 例如主机名和错误代码的字段,并丢弃其他所有内容。)

接下来,通过更改或后处理日志文件,让您的生活变得轻松:

nps.agent.14b.no other attempt was made

为:

nps.agent.14b:no other attempt was made

现在你只需分开&#39;:&#39; (或&#39; |&#39;) 看看日志文件的一些最佳实践,已经写了很多好东西。 如果保证每一行都有一个且只有一个主机名和一个错误代码,可以将它们存储为单独的Hostname和ErrorCode字段。

因此,您的代码应该像以下一样简单:

> as.factor(strsplit(s, ':')
[1] 'nps.agent.14b'             'no other attempt was made'

同样,如果您没有必要处理&#39;没有进行任何其他尝试,那么请不要存储它。或者您的日志文件消息可以将其压缩为“NEA”。或者如果它没有传达任何额外信息,就把它扔掉。

我建议您重新访问日志文件格式,并尽可能简洁明了地提供信息。