2

ユーザー定義関数 (dist.func) が実行され、データの 1 行で使用すると正しい出力が得られますが、apply() コマンドに埋め込むと正しい出力が得られません (まだ実行されます)。この場合、行ごとに計算したいと思います。

複雑なサンプル データが含まれていることをお詫びしますが、意味のある出力を返すには、値がしきい値内に収まる必要があります。これが確実に発生する最も簡単な方法です。

library(fields)

この関数は基本的に XY 座標間 (rdist() コマンドによるユークリッド距離) を測定しますが、最初にデータのサブセットを取得し、特定の類似性 (最初の座標と第 2 主成分、PC1 および PC2)。

これにより、サンプル データが次のようになります。

# This data is the reference points to measure FROM
FROM <- data.frame(X=c(-4187500,-4183500,-4155500,-4179500,-2883500),
               Y=c(10092500,10084500,10020500,10012500,9232500),
               PC1=c(-0.525,-0.506,-1.146,-0.733,-1.160),
               PC2=c(3.606,3.609,4.114,3.681,0.882))

# This data is the destination points to measure TO
TO <- data.frame(X=c(-4207500,-4183500,-4203500,-4187500,-2827500,-4203500,-4199500,-4183500,-4195500,-4191500),
             Y=c(10100500,10100500,10096500,10092500,10092500,10088500,10084500,10084500,10072500,10064500),
             PC1=c(-0.371,0.447,-0.344,-0.026,-0.652,-0.460,-0.313,0.010,-0.293,-0.319 ),
             PC2=c(3.149,4.619,3.318,3.885,0.407,3.164,3.300,3.892,3.226,3.337))

# This is the threshold of the data similarity match (distance between PC1 and PC2 in both data sets)
threshold <- 0.5

これが私のユーザー定義関数です(各行の説明付き):

dist.func <- function(REF){
  # Calculate the similarity (PC1 and PC2 distance) to all points in the destination
  # Select only those under the threshold
  bt <- as.matrix(TO[(rdist(REF[3:4],TO[3:4])[1,]<threshold)==T,c("X","Y")])
  # Calculate the number of points under the threshold (the "sample size")
  # If there are no points uder the threshold, the SS is set to zero (otherwise 'NA' kills the loop)
  ss <- ifelse(nrow(bt)>=50, 50 ,nrow(bt))
  # If/else to deal with SS=0
  if (nrow(bt)>0) {
    # Calculate the euclidian distance between the reference point and all points under the threshold
    # This calculates the distances, sorts them in ascending order, and trims to the sample size
    dst <- rdist(REF[1:2],bt)[1,][order(rdist(REF[1:2],bt)[1,])][1:ss]
  } else {
  dst <- c(NA)
  }
# Report (in a list or table or whatever) the summary stats for the distances 
list(
  p05=ifelse(nrow(bt)==0, NA, quantile(dst,0.05)),
  MIN=ifelse(nrow(bt)==0, NA, min(dst)),
  AVG=ifelse(nrow(bt)==0, NA, mean(dst)),
  N=ifelse(nrow(bt)==0, 0, nrow(bt)))
}

FROM データの 1 行 (動作中) と apply() コマンドに埋め込まれた (正しい値を返さない) テストは次のとおりです。

# Using the function on a single line of data returns correct values for the given line
dist.func(FROM[1,])

# Embedding the function into apply() returns incorrect outputs
# I'm committed to using apply() here (or some variant) to avoid a for() loop by rows
apply(FROM, 1, dist.func)

私はユーザー定義関数にかなり慣れていないので、そこに問題がある場合は、そこにある提案をいただければ幸いです。また、関数またはコード全体をより効率的にする方法 (私がよく知らないパッケージ) があれば、それも大歓迎です。

4

2 に答える 2

2

lapply正しい出力を与える

  my.list<-as.list(1:nrow(FROM))

k- lapply(my.list,function(i)dist.func(FROM[i,])
kk<-do.call(rbind,k) # convert to data.frame

sapply(my.list,function(i)dist.func(FROM[i,]))
    [,1]     [,2]     [,3] [,4] [,5]
p05 14939.76 16242.64 NA   NA   NA  
MIN 14422.21 16000    NA   NA   NA  
AVG 19795.44 21179.25 NA   NA   NA  
N   6        6        0    0    0  
于 2013-10-08T23:17:47.710 に答える