0

したがって、2 つのファイル (スペース区切り) があり、file1 の行名は file2 からランダムに取得されますが、file1 には複数の列があり、file2 には行名の列しかありません。減算の最小絶対値に従って、ファイル 2 の残りの列がファイル 1 から取得されるファイル 2 を再生成したいと考えています。

例えば:

ファイル1:

5 0.1 0.2 0.5
20 0.3 0.3 0.6
30 0.5 0.66 0.1
100 0.9 0 1

file1、5、20、30、および 100 の最初の列はすべて file2 からのものです。

ファイル 2:

2
5
19
20
27
30
65
100
105

このファイルには行名しかありません。このファイルには、ファイル 1 の 5、20、30、および 100 が含まれています。

望ましい出力:

2 0.1 0.2 0.5
5 0.1 0.2 0.5
19 0.3 0.3 0.6
20 0.3 0.3 0.6
27 0.5 0.66 0.1
30 0.5 0.66 0.1
65 0.5 0.66 0.1
100 0.9 0 1
105 0.9 0 1

両方のファイルは、列 1 で最小から最大の順に並べ替えられます。基本的に、file2 の各番号で、file1 の絶対値が最小である column1 の行から残りの列を取得する必要があります。たとえば、file2 の最初の数は 2 で、2 の絶対値が最小で 5 であるため、その行には file1 の残りの列、「5」の行があります。同点の場合、つまり 2 つの行が減算されたときに同じ絶対値を持つことを意味し、出力は小さい方の数の行から列を取得します。たとえば、ファイル 2 の 65 は、ファイル 1 の 30 と 100 の絶対値が等しいため、小さい方の 30 行から値を取得します。

私はRでこれをやろうとしていましたが、ここに私のコードがあります:

i<-1
b<- data.frame(stringsAsFactors=FALSE)
N<- 4 ## number of lines in file1
Row <- 9 ## number of lines in file2
while (i<=Row) {
test <- which(abs(file1[,1] - rep(file2[i,1],N)) == min(abs(file1[,1] - rep(file2[i,1], N)))); ## repeating the value of file2 N times and find the smallest with file1 by subtraction
    if (length(test) == 1) {  ## find 1 smallest value
        a<- file1[test,]; b<-rbind(b, a)
    }
    else if (length(test) == 2) {  ## tie, get the first value, the"smaller one"
        a<- file1[(head(test,1)),]; b<-rbind(b, a)
    } 
    else {warning("There is an error; test is neither 1 or 2")}; i<-i+1
}

output <- b
output$V1 <- NULL

ファイル1とファイル2が非常に大きくなると、動作しますが非常に遅くなります。これを行うより速い方法はありますか?awk、shell、R、Perl、python など、すべてのメソッドを歓迎します。

4

3 に答える 3

0
V1_2 <- unlist(lapply(file2$V1, function(x) file1$V1[which.min(abs(x - file1$V1))]))
file2 <- cbind.data.frame(file2, V1_2)
merge(file2, file1, by.x = "V1_2", by.y = "V1", all.x = TRUE)
于 2013-08-30T01:05:15.850 に答える
0

行名なしで読むと、これがはるかに簡単になります。ヘルパー関数を使用したアプローチは次のとおりです。

nearest <- function(x, y){
    o <- outer(x,y,function(x,y)abs(x-y))
    a <- apply(o, 1, which.min)
    y[a]
}

データの読み取り:

file1 <- read.table(header=FALSE,text="
5 0.1 0.2 0.5
20 0.3 0.3 0.6
30 0.5 0.66 0.1
100 0.9 0 1
")

file2 <- read.table(header=FALSE,text="
2
5
19
20
27
30
65
100
105
")

結果:

merge(within(file2, {V1_old <- V1; V1 <- nearest(V1, file1$V1)}), file1, all.x=TRUE)

   V1 V1_old  V2   V3  V4
1   5      2 0.1 0.20 0.5
2   5      5 0.1 0.20 0.5
3  20     19 0.3 0.30 0.6
4  20     20 0.3 0.30 0.6
5  30     27 0.5 0.66 0.1
6  30     30 0.5 0.66 0.1
7  30     65 0.5 0.66 0.1
8 100    100 0.9 0.00 1.0
9 100    105 0.9 0.00 1.0
于 2013-08-30T00:53:52.807 に答える