如何计算几个文件的相关性?

时间:2012-12-03 09:17:00

标签: r binary correlation

在两个目录dir1和dir2中有365个二进制文件,它们具有相同的格式,字节,扩展等...

下面给出的代码将在dir1和dir2中作为向量读取,然后计算相关性。  基本上我想要得到相关图,我们只计算每个网格像素的R值。假设我们想要计算dir1和dir2之间的全局相关性图,我们为每个像素提供了来自dir1和dir2的两列数据,并且可以计算该像素的R值,然后简单地对全局像素进行循环。

dir1 <- list.files("C:\\cor", "*.bin", full.names = TRUE)
dir2 <- list.files("C:\\cor2", "*.bin", full.names = TRUE)
results <- list()
    for (.files in dir1){
# read in the 365 files as a vector of numbers for dir1
    file1 <- do.call(rbind,(lapply(.files, readBin  , integer() , size = 2 ,
                                n = 360 * 720 , signed = T)))
    }
    for (.files in dir2){
    # read in the 365 files as a vector of numbers for dir2
    file2<- do.call(rbind,(lapply(.files, readBin  , integer() , size = 2 , 
                    n = 360 * 720 , signed = T)))
    }
    # calculate the  correlation so we will get a correlation map
for (.files in seq_along(dir1)){              
    results[[length(results) + 1L]]<- cor(file1 ,file2)
    }

我收到此错误:Error in cor(file1, file2) : allocMatrix: too many elements specified

2 个答案:

答案 0 :(得分:3)

如果你想计算每个x,y位置的时间相关性(看起来如此),我会把它读成一个维度为(nx, ny, ntsteps, ndatasets)的多维数组,例如使用较小的示例数据集:

          # nx   ny   nsteps ndatasets
dat = runif(20 * 30 * 100 *  2)
dim(dat) = c(20, 30, 100, 2)
> str(dat)
num [1:20, 1:30, 1:100, 1:2] 0.969 0.482 0.974 0.682 0.856 ...

现在我们利用apply也适用于多维数组而不仅仅是矩阵的事实:

cor_result = apply(dat, c(1,2), function(x) cor(x[,1], x[,2]))
> str(cor_result)
 num [1:20, 1:30] 0.06673 0.00943 -0.11265 -0.01157 -0.0024 ...

我们使用apply迭代所有x,y对来计算时间相关性。

关于您的大数据集,加载它需要大约1.4 Gb。 R中的经验法则是,您需要3倍于RAM的数据集大小才能使用它。所以,如果你有8 Gb的RAM和64位的R,这应该可以正常工作。或者,我经常在块中进行这些计算,因为我只有4 Gb。例如,您可以先处理前5行(y坐标),然后处理第2行等等。

答案 1 :(得分:2)

我会按照以下方式重写您的代码(假设我理解正确,您想要做的是将file1的每一行与file2的每一行进行比较):

dir1 <- list.files("C:\\cor", "*.bin", full.names = TRUE)
dir2 <- list.files("C:\\cor2", "*.bin", full.names = TRUE)
file1 <- do.call(rbind,lapply(dir1, readBin  , integer() , size = 2 ,
                                n = 360 * 720 , signed = T))
file2 <- do.call(rbind,lapply(dir2, readBin  , integer() , size = 2 ,
                                n = 360 * 720 , signed = T))
results <- apply(file1, 1, function(x){ apply(file2, 1, function(X){cor(x, X)})})

results将是一个矩阵(365 x 365),例如你的第x行file1(因此,dir1中的第x个文件)和第2行file2之间的相关系数(因此,dir2)中的第y个文件是results[x,y]。然后,您可以使用函数image(results)直接将其绘制为热图。

编辑:澄清代码的最后一行:它完全对应于以下for循环:

results <- array(dim = c(length(file1), length(file2)))
for(i in 1:length(file1)){
    for(j in 1:length(file2)){
        results[i,j]<-cor(file1[i, ], file2[j, ])
        }
    }

根据评论编辑: @PaulHiemstra比我快,但实际上我打算提出类似的建议:

dir1 <- list.files("C:\\cor", "*.bin", full.names = TRUE)
dir2 <- list.files("C:\\cor2", "*.bin", full.names = TRUE)
file_tot<-array(dim=c(360,720,365,2))
for(i in 1:length(dir1)){
    file_tot[,,i,1] <- readBin(dir1[i], integer(), size = 2 ,n = 360 * 720 , signed = T)
    file_tot[,,i,2] <- readBin(dir2[i], integer(), size = 2 ,n = 360 * 720 , signed = T)
    }
results<-apply(file_tot,c(1,2),function(x){cor(x[,1],x[,2])})