我有一个看起来像这样的医学数据集:
patient_id disease_id
1111111111 DISEASE:1
1111111111 DISEASE:2
1111111111 DISEASE:3
1111111111 DISEASE:4
1111111111 DISEASE:5
1111111111 DISEASE:6
1111111111 DISEASE:6
1111111112 DISEASE:1
1111111112 DISEASE:2
1111111112 DISEASE:4
1111111113 DISEASE:1
1111111113 DISEASE:5
我需要输入神经网络/随机森林模型。因此,唯一想到的自然数据表示形式就是:
patient_id DISEASE:1 DISEASE:2 DISEASE:3 DISEASE:4 DISEASE:5 DISEASE:6 ...
11111111111 1 1 1 1 1 1 ...
11111111112 1 1 0 1 0 0 ...
11111111113 1 0 0 0 1 0 ...
但是我的数据集非常大(〜50GB,压缩后的1.5 GB),并且具有大量的disease_id
,因此在R中以最有效的方式重塑该数据需要在压缩后的中有11.7 TB的空间RD格式(我知道这是因为我将数据集分为100个块,并且对单个数据集进行重塑会产生117 GB的沉重RD文件;将其中的100个合并将产生大于11.7TB的空间)。
现在,我有5个需要合并的大数据集,所以我感觉有些卡住。我需要提出一个更有效的数据表示形式,但不知道如何处理需要1-hot编码的分类变量。任何人都可以建议其他替代方法来处理此类数据。
您提出了一个有趣的问题。用R
分析该数据量将是一次真正的改变。
所以,我只能给您一般建议。首先,我认为您需要分离RAM和磁盘存储。使用Rds
不会帮助您改善整形的效率,但与csv
相比,它将在磁盘上产生较小的数据。
如果您要采用内存方式,除了使用data.table::dcast
之外,我没有其他可能性。在这种情况下,请遵循@Ronak Shah的建议:
library(data.table)
setDT(df)
df[, n := 1]
dcast(unique(df), patient_id~ disease_id, value.var = "n", fill = 0)
对于海量数据,我认为内存不是最合适的。您可能会看一下数据库方法(尤其是postgreSQL
)或Spark
数据库您可以使用几个选项来使用postgreSQL
中的R
。其中之一是dbplyr:如果您知道tidyverse
语法,就会发现熟悉的动词。与标准R
数据框相比,数据透视表操作对数据库而言有些棘手,但您可能会发现some ways to do that。您可以找到比我更多的数据库专家,这将给您带来很多有趣的窍门。
spark Spark
可以很好地进行重塑,如果您可以在伺服器中的执行者之间分散任务。如果您使用的是个人计算机(独立模式),则仍可以并行执行内核之间的任务,但是不要忘记更改会话的spark.memory.fraction
参数,否则我认为您可能会遇到out of memory
问题。我比pyspark
更习惯sparkR
,但我认为逻辑是相同的。
自Spark 1.6
起,您就可以透视数据(ex: pyspark doc)。这样可以实现wide
到long
的转换。本着这种精神
df.withColumn("n", psf.lit(1)).pivot("patient_id").sum("n")
您使用Rds
。您需要对某些格式进行更多压缩,例如fst
。 parquet
文件也非常压缩,这也许是存储大量数据的最佳选择之一。您可以使用Spark
或使用arrow
软件包阅读它们