Вычислить абсолютную разницу между значениями в двух столбцах

Я пишу код R для подсчета / выбора строк с абсолютной разницей двух значений в двух столбцах меньше определенного значения (скажем, 0,1). Он считывает два файла и два номера столбца, на основании которых выполняется расчет.

args<-commandArgs(TRUE)
f1<-args[1]
f2<-args[2]
col1<-args[3]
col2<-args[4]

if (length(args) <4) {
    stop("\n\nUsage: file1 file2 column1 column2 >output\n\n")
}
pearsoncor<-function(in1,in2,x,y){
# Read in data
file1<-read.table(in1,header=F)
file2<-read.table(in2,header=F)
col1<-as.integer(x)
col2<-as.integer(y)

# Calculate pearson correlation

    cor_r <- which(file1[,col1] != '.' & file2[,col2] != '.')
    file1.filter<-file1[cor_r,col1]
    file2.filter<-file2[cor_r,col2]
    x=cor.test(c(file1.filter),c(file2.filter),method="pearson")
    fname=paste(basename(in1), " and ", basename(in2),sep="")
    print(fname)
    print(x)
    conc_c <- 0
    for (i in 1:length(cor_r)) 
    {
        dif<-abs(file1.filter[i,] - file2.filter[i,])
        if (dif <0.1){
            conc_c = conc_c +1
        }
    }
    print(conc_c)
}

pearsoncor(f1,f2,col1,col2)

Тестовые файлы: два тестовых файла, разделенных табуляцией.

==> t1.txt <==
chr1    10468   10470   .       1       +       chr1    10468   10470   0.762   2
chr1    10470   10472   .       2       +       chr1    10470   10472   0.738   2
chr1    10483   10485   .       3       +       chr1    10483   10485   0.865   2
chr1    10488   10490   .       4       +       chr1    10488   10490   0.825   2
chr1    10492   10494   .       5       +       chr1    10492   10494   0.894   2
chr1    10496   10498   .       6       +       chr1    10496   10498   0.859   2
chr1    10524   10526   .       7       +       chr1    10524   10526   0.954   2
chr1    10541   10543   .       8       +       chr1    10541   10543   0.876   2
chr1    10562   10564   .       9       +       chr1    10562   10564   0.829   2
chr1    10570   10572   .       10      +       chr1    10570   10572   .   2

==> t2.txt <==
chr1    10468   10470   .       1       +       chr1    10468   10470   0.69    2
chr1    10470   10472   .       2       +       chr1    10470   10472   0.7     2
chr1    10483   10485   .       3       +       chr1    10483   10485   0.911   2
chr1    10488   10490   .       4       +       chr1    10488   10490   0.894   2
chr1    10492   10494   .       5       +       chr1    10492   10494   0.714   2
chr1    10496   10498   .       6       +       chr1    10496   10498   0.857   2
chr1    10524   10526   .       7       +       chr1    10524   10526   0.984   2
chr1    10541   10543   .       8       +       chr1    10541   10543   0.955   2
chr1    10562   10564   .       9       +       chr1    10562   10564   0.981   2
chr1    10570   10572   .       10      +       chr1    10570   10572   0.979   2

Бежать:

Rscript script.r t1.txt t2.txt 10 10

Я не мог вычислить абсолютное значение в коде ... он выдал эту ошибку:

Error in `[.default`(file1.filter, i, ) : incorrect number of dimensions
Calls: pearsoncor.jgu -> [ -> [.factor -> NextMethod
Execution halted

Также отсюда появилась первая строка сообщения об ошибке:

> file1.filter[1,]
Error in `[.default`(file1.filter, 1, ) : incorrect number of dimensions

> dput(head(file1.filter))
c(0.762, 0.738, 0.865, 0.825, 0.894, 0.859)

person olala    schedule 15.12.2015    source источник


Ответы (1)


file1.filter и file2.filter являются векторами, поэтому синтаксис file1.filter[i,] вызывает ошибку и может быть исправлен простым использованием file1.filter[i] (вам также необходимо использовать file2.filter[i]).

При этом все, что вы делаете с циклом for, - это подсчет количества раз, когда элементы двух векторов отличаются не более чем на 0,1:

conc_c <- 0
for (i in 1:length(cor_r)) 
{
    dif<-abs(file1.filter[i,] - file2.filter[i,])
    if (dif <0.1){
        conc_c = conc_c +1
    }
}
print(conc_c)

Это можно сделать одной строкой в ​​R:

print(sum(abs(file1.filter - file2.filter) < 0.1))

Обычно abs(file1.filter - file2.filter) < 0.1 возвращает вектор того, находится ли каждый элемент на расстоянии менее 0,1 друг от друга, а sum добавляет 1 для каждого значения TRUE и 0 для каждого значения FALSE, эффективно суммируя количество TRUE значений в векторе.

person josliber♦    schedule 15.12.2015
comment
Спасибо за помощь. с моей стороны есть еще одна проблема. Я поместил только 10 строк в качестве тестового файла, но в реальном файле миллионы строк, и file1.filter ‹-file1 [cor_r, col1] дал мне что-то не вектор .. у него есть уровни .. - person olala; 15.12.2015
comment
Я думаю, это потому, что в некоторых строках есть. в 10-м столбце - person olala; 15.12.2015
comment
так что я думаю, что могу использовать ответы из этого сообщения, чтобы решить эту проблему: stackoverflow.com/questions/3418128/ - person olala; 15.12.2015
comment
@olala Мы действительно не сможем помочь вам с проблемами отладки, если вы не предоставите воспроизводимые примеры. - person josliber♦; 15.12.2015
comment
извините, я понял это ... я только что случайно увидел 10-й столбец в последней строке t1.txt, который может воспроизвести мою проблему сейчас ... извините за это. можешь взглянуть? Благодарность! @josilber - person olala; 15.12.2015
comment
у меня это работает: print (sum (abs (as.numeric (paste (file1.filter)) - as.numeric (paste (file2.filter))) ‹0,1)) - person olala; 15.12.2015