删除重复项需要转置,但我的数据框太大
Removing duplicates requires a transpose, but my dataframe is too large
我问了一个问题 here。我有一个简单的数据框,我试图为其删除重复项。非常基本的问题。
Ak运行 给出了一个很好的答案,就是使用这一行:
df[!duplicated(data.frame(t(apply(df[1:2], 1, sort)), df$location)),]
我继续这样做,这对虚拟问题很有效。但我有 350 万条记录要过滤。
为了找出瓶颈所在,我将代码分解为多个步骤。
step1 <- apply(df1[1:2], 1, sort)
step2 <- t(step1)
step3 <- data.frame(step2, df1$location)
step4 <- !duplicated(step3)
final <- df1[step4, ,]
第 1 步看起来很长,但这并不是最糟糕的。
然而,第 2 步显然是罪魁祸首。
所以我处于一种不幸的情况,我正在寻找一种在 R 中转置 350 万行的方法。(或者可能不在 R 中。希望有某种方法可以在某个地方做到这一点)。
环顾四周,我看到了一些想法
安装 WGCNA 库,它具有 transposeBigData
功能。不幸的是,这个包不再被维护,我无法安装所有的依赖项。
将数据写入csv,然后逐行读取,逐行逐行转置。对我来说,甚至一夜之间写完文件 运行 也没有完成。
这真是奇怪。我只想删除重复项。出于某种原因,我必须在此过程中转置数据框。但是我不能转置这么大的数据框。
所以我需要一个更好的策略来删除重复项或转置。有人对此有任何想法吗?
顺便说一句,我使用的是 Ubuntu 14.04,内存为 15.6 GiB,cat /proc/cpuinfo
returns
英特尔(R) 酷睿(TM) i7-3630QM CPU @ 2.40GHz
型号名称:Intel(R) Core(TM) i7-3630QM CPU @ 2.40GHz
cpu 兆赫:1200.000
缓存大小:6144 KB
谢谢。
df <- data.frame(id1 = c(1,2,3,4,9), id2 = c(2,1,4,5,10), location=c('Alaska', 'Alaska', 'California', 'Kansas', 'Alaska'), comment=c('cold', 'freezing!', 'nice', 'boring', 'cold'))
更快的选择是使用 pmin/pmax
和 data.table
library(data.table)
setDT(df)[!duplicated(data.table(pmin(id1, id2), pmax(id1, id2)))]
# id1 id2 location comment
#1: 1 2 Alaska cold
#2: 3 4 California nice
#3: 4 5 Kansas boring
#4: 9 10 Alaska cold
如果还需要包含'location'才能找到unique
setDT(df)[!duplicated(data.table(pmin(id1, id2), pmax(id1, id2), location))]
因此,在周末的大部分时间都为此苦苦挣扎之后(感谢来自杰出的@akrun 的大量无私帮助),我意识到我需要以完全不同的方式来解决这个问题。
由于数据框太大而无法在内存中处理,我最终使用了一种策略,我将一个(字符串)键粘贴在一起并将其列绑定到数据框上。接下来,我折叠了键并对字符进行了排序。在这里我可以使用 which
来获取包含非重复键的行的索引。这样我就可以过滤我的数据框。
df_with_key <- within(df, key <- paste(boxer1, boxer2, date, location, sep=""))
strSort <- function(x)
sapply(lapply(strsplit(x, NULL), sort), paste, collapse="")
df_with_key$key <- strSort(df_with_key$key)
idx <- which(!duplicated(df_with_key$key))
final_df <- df[idx,]
我问了一个问题 here。我有一个简单的数据框,我试图为其删除重复项。非常基本的问题。
Ak运行 给出了一个很好的答案,就是使用这一行:
df[!duplicated(data.frame(t(apply(df[1:2], 1, sort)), df$location)),]
我继续这样做,这对虚拟问题很有效。但我有 350 万条记录要过滤。
为了找出瓶颈所在,我将代码分解为多个步骤。
step1 <- apply(df1[1:2], 1, sort)
step2 <- t(step1)
step3 <- data.frame(step2, df1$location)
step4 <- !duplicated(step3)
final <- df1[step4, ,]
第 1 步看起来很长,但这并不是最糟糕的。
然而,第 2 步显然是罪魁祸首。
所以我处于一种不幸的情况,我正在寻找一种在 R 中转置 350 万行的方法。(或者可能不在 R 中。希望有某种方法可以在某个地方做到这一点)。
环顾四周,我看到了一些想法
安装 WGCNA 库,它具有
transposeBigData
功能。不幸的是,这个包不再被维护,我无法安装所有的依赖项。将数据写入csv,然后逐行读取,逐行逐行转置。对我来说,甚至一夜之间写完文件 运行 也没有完成。
这真是奇怪。我只想删除重复项。出于某种原因,我必须在此过程中转置数据框。但是我不能转置这么大的数据框。
所以我需要一个更好的策略来删除重复项或转置。有人对此有任何想法吗?
顺便说一句,我使用的是 Ubuntu 14.04,内存为 15.6 GiB,cat /proc/cpuinfo
returns
英特尔(R) 酷睿(TM) i7-3630QM CPU @ 2.40GHz
型号名称:Intel(R) Core(TM) i7-3630QM CPU @ 2.40GHz
cpu 兆赫:1200.000
缓存大小:6144 KB
谢谢。
df <- data.frame(id1 = c(1,2,3,4,9), id2 = c(2,1,4,5,10), location=c('Alaska', 'Alaska', 'California', 'Kansas', 'Alaska'), comment=c('cold', 'freezing!', 'nice', 'boring', 'cold'))
更快的选择是使用 pmin/pmax
和 data.table
library(data.table)
setDT(df)[!duplicated(data.table(pmin(id1, id2), pmax(id1, id2)))]
# id1 id2 location comment
#1: 1 2 Alaska cold
#2: 3 4 California nice
#3: 4 5 Kansas boring
#4: 9 10 Alaska cold
如果还需要包含'location'才能找到unique
setDT(df)[!duplicated(data.table(pmin(id1, id2), pmax(id1, id2), location))]
因此,在周末的大部分时间都为此苦苦挣扎之后(感谢来自杰出的@akrun 的大量无私帮助),我意识到我需要以完全不同的方式来解决这个问题。
由于数据框太大而无法在内存中处理,我最终使用了一种策略,我将一个(字符串)键粘贴在一起并将其列绑定到数据框上。接下来,我折叠了键并对字符进行了排序。在这里我可以使用 which
来获取包含非重复键的行的索引。这样我就可以过滤我的数据框。
df_with_key <- within(df, key <- paste(boxer1, boxer2, date, location, sep=""))
strSort <- function(x)
sapply(lapply(strsplit(x, NULL), sort), paste, collapse="")
df_with_key$key <- strSort(df_with_key$key)
idx <- which(!duplicated(df_with_key$key))
final_df <- df[idx,]