1

Mandar 已经从r 中的这个 Q/A 中慷慨地为我编写了这段代码,如何根据其他向量评估这两个向量

names(df) <- c("a","b","c","d")
df_backup <- df
df$newcol <- NA

used <- c()
for (i in seq(1,length(df$a),1)){
  print("######## Separator ########")
  print(paste("searching right match that fits criteria for ",df$a[i],"in column 'a'",sep=""))
  valuea <- df[i,1]
  orderx <- order(abs(df$b-valuea))

  index=1
  while (is.na(df$newcol[i])) {
    j=orderx[index]
    if (df$b[j] %in% used){
      print(paste("passing ",df$b[j], "as it has already been used",sep=""))
      index=index+1
      next
    } else {
      indexb <- j
      valueb <- df$b[indexb]
      print(paste("trying ",valueb,sep=""))

      if (df$c[i] != df$d[indexb]) {
        df$newcol[i] <- df$b[indexb]
        print(paste("using ",valueb,sep=""))
        used <- c(used,df$b[indexb])
      } else {
        df$newcol[i] <- NA
        print(paste("cant use ",valueb,"as the column c (related to index in a) and d (related to index in b) values are matching",sep=""))
      }

      index=index+1
    }
  }
}

这就是我的数据的样子

a   b   c   d
12.9722051  297.9117268 1   1
69.64816997 298.1908749 2   2
318.8794557 169.0386352 3   3
326.1762208 169.3201391 4   4
137.5400592 336.6595313 5   5
358.0600171 94.70890334 6   6
258.9282428 94.77530919 7   7
98.57513917 290.1983195 8   8
98.46303072 290.4078981 9   9
17.2276417  344.383796  10  10
316.6442074 148.786547  11  11
310.7370168 153.3287735 12  12
237.3270752 107.8397117 13  13
250.6538555 108.0570571 14  14
337.0954288 180.6311769 15  15
137.0336521 1.0294907   16  16
301.2277242 185.2062845 17  17
332.935301  185.9792236 18  18
340.841266  220.4043846 19  19

a 和 b 列中的值是罗盘方位。目前,该公式查看 a 列中的值并将其与 b 列中的所有值进行比较,并找到最接近的值。但我意识到我需要它做的是查看 b 列中的值,但不仅要根据绝对差找到最接近的值,还要考虑到它是指南针方位。例如:对于 358.0600171 的 a 列中的值,当前公式将返回 344.383796 的 b 列中的值,该值距 358.060171 约 14 度;但是,b 列中实际最接近的方位角值应该是 1.0294907,距​​离 358.0600171 仅 3 度。我想在当前公式中加入一个解决此罗盘方位问题的函数:它执行我所有其他需要的评估、过滤和列创建。

这里有一个类似的查询(找到指南针的 2 度之间的最接近差异 - Javascript),但我需要有关该函数是否可以在 R 中工作以及如何将其合并到现有公式中的帮助。

4

3 回答 3

1

我们可以像这样找到最近的罗盘方位:

nearest = function(i,df){
  diff = abs(df[i, 1] - df[, 2])
  diff = pmin(diff, 360-diff)
  which.min(diff)
}

df$nearest_b = sapply(1:NROW(df), nearest, df[1:2])
df$nearest_a = sapply(1:NROW(df), nearest, df[2:1])

#            a          b nearest_b nearest_a
# 1   12.97221 297.911727        16        17
# 2   69.64817 298.190875         6        17
# 3  318.87946 169.038635         5         5
# 4  326.17622 169.320139         5         5
# 5  137.54006 336.659531        11        15
# 6  358.06002  94.708903        16         9
# 7  258.92824  94.775309         8         9
# 8   98.57514 290.198320         7        17
# 9   98.46303 290.407898         7        17
# 10  17.22764 344.383796        16        19
# 11 316.64421 148.786547         2         5
# 12 310.73702 153.328774         2         5
# 13 237.32708 107.839712        19         8
# 14 250.65386 108.057057        19         8
# 15 337.09543 180.631177         5         5
# 16 137.03365   1.029491        11         6
# 17 301.22772 185.206285         2         5
# 18 332.93530 185.979224         5         5
# 19 340.84127 220.404385        10        13

数据

df = read.table(text =
"a   b   c   d
12.9722051  297.9117268 1   1
69.64816997 298.1908749 2   2
318.8794557 169.0386352 3   3
326.1762208 169.3201391 4   4
137.5400592 336.6595313 5   5
358.0600171 94.70890334 6   6
258.9282428 94.77530919 7   7
98.57513917 290.1983195 8   8
98.46303072 290.4078981 9   9
17.2276417  344.383796  10  10
316.6442074 148.786547  11  11
310.7370168 153.3287735 12  12
237.3270752 107.8397117 13  13
250.6538555 108.0570571 14  14
337.0954288 180.6311769 15  15
137.0336521 1.0294907   16  16
301.2277242 185.2062845 17  17
332.935301  185.9792236 18  18
340.841266  220.4043846 19  19",
header = T)[,1:2]
于 2017-01-26T22:00:16.460 回答
0

检查此代码: 刚刚更改了 orderx 使用 ifelse 定义的方式现在如果角度之间的绝对差 > 180,则使用 360 差(这是较低的值);否则,如果差异已经 <=180,则使用较小的差异本身

setwd("~/Desktop/")
df <- read.table("trial.txt",header=T,sep="\t")
names(df) <- c("a","B","C","D")
df_backup <- df
df$newcol <- NA

used <- c()
for (i in seq(1,length(df$a),1)){
  print("######## Separator ########")
  print(paste("searching right match that fits criteria for ",df$a[i],"in column 'a'",sep=""))
  valueA <- df[i,1]
  # orderx <- order(abs(df$B-valueA))
  orderx <- order(ifelse(360-abs(df$B-valueA) > 180, abs(df$B-valueA) ,360-abs(df$B-valueA)))

  index=1
  while (is.na(df$newcol[i])) {
    j=orderx[index]
    if (df$B[j] %in% used){
      print(paste("passing ",df$B[j], "as it has already been used",sep=""))
      index=index+1
      next
    } else {
      indexB <- j
      valueB <- df$B[indexB]
      print(paste("trying ",valueB,sep=""))

      if (df$C[i] != df$D[indexB]) {
        df$newcol[i] <- df$B[indexB]
        print(paste("using ",valueB,sep=""))
        used <- c(used,df$B[indexB])
      } else {
        df$newcol[i] <- NA
        print(paste("cant use ",valueB,"as the column C (related to index in A) and D (related to index in B) values are matching",sep=""))
      }

      index=index+1
    }
  }
}
于 2017-02-07T19:00:50.427 回答
0

geosphere 包有一些包含球点之间距离的函数。

ftp://cran.r-project.org/pub/R/web/packages/geosphere/geosphere.pdf

我不确定它是否是您正在寻找的 - 您可能必须弄清楚数据中的罗盘方位如何转换为您需要的输入。

我注意到您遇到的问题是将绝对距离视为数值差异,而不考虑您应该在 360 处重置为 0 的事实。您可以通过编写一个规定 sum (坐标和360)和(其他坐标)之间的差异。

例如: - c1 是输入坐标 - c2 是您要与之比较的坐标

if c1 - c2 > 180 { (360 - c1) + c2 }

我不完全理解您要做什么,因此不确定这是否正确,但希望对您有所帮助。

于 2017-01-26T19:59:33.187 回答