【问题标题】:Random sampling over XY coordinates in R (or in Matlab ??)在 R(或 Matlab 中??)中对 XY 坐标进行随机采样
【发布时间】:2013-01-30 17:58:57
【问题描述】:

我的数据框有以下四列:类型(“A”或“B”)、xvar、经度和纬度。它看起来像:

      type    xvar    longitude    latitude
[1,]   A       20      -87.81        40.11
[2,]   A       12      -87.82        40.12
[3,]   A       50      -87.85        40.22
....
[21,]  B       24      -87.79        40.04
[22,]  B       30      -87.88        40.10
[23,]  B       12      -87.67        40.32
[24,]  B       66      -87.66        40.44
....

type="A" 有 20 行,type="B" 有 25,000 行。我的任务是将 20 个“A”数据点的 xvar 值随机分配到“B”类型的 X-Y 空间而不进行替换。例如,在 type="A" 的第一次观察中的 xvar=20 可以随机位于 [22,] 中,即 (-87.88,40.10) 。因为我在没有替换的情况下这样做,理论上,我可以进行 25,000/20 = 1,250 次复制。我想要 1,000 次复制。

我有一个函数(比如 myfunc(xvar,longitude,latitude)),它从一个随机样本中返回一个统计值。我首先创建一个 1,000x1 的空矩阵(例如 myresult)。

myresult <- array(0,dim=c(1000,1))

然后,对于每个随机样本,我应用我的函数 (myfunc) 来计算统计量。

for (i in seq(1:1000)) {
  draw one sample, that has three variables: xvar, longitude, latitude.
  apply my function to this selected sample.
  store the calculated statistic in the myresult[i,]
}

我想知道如何在 R 中执行此操作。(可能在 Matlab 中??)谢谢!

================================================ ===============

更新:@user。借用你的想法,以下是我想要的:

dd1 <- df[df$type == "B" ,] 
dd2 <- df[df$type == "A" ,]
v   <- dd2[sample(nrow(dd2), nrow(dd2)), ]
randomXvarOfA <- as.matrix(v[,c("xvar")])  
cols <- c("longitude","latitude")
B_shuffled_XY <- dd1[,cols][sample(nrow(dd1), nrow(dd2)), ]
dimnames(randomXvarOfA)=list(NULL,c("xvar"))
sampledData <- cbind(randomXvarOfA,B_shuffled_XY)
sampledData

   xvar longitude latitude
4   20    -87.79    40.04
7   12    -87.66    40.44
5   50    -87.88    40.10

【问题讨论】:

  • 您只是想更改 lat long 值还是也将 xvar 添加到 Bs 中?

标签: r random sampling


【解决方案1】:

读入你的数据:

  df<- read.table( text="
      type    xvar    longitude    latitude
      A       20      -87.81        40.11
      A       12      -87.82        40.12
      A       50      -87.85        40.22
      B       24      -87.79        40.04
      B       30      -87.88        40.10
       B       12      -87.67        40.32
      B       66      -87.66        40.44", header = TRUE)

我在写这篇文章时没有拆分,它看起来很乱。 所以我决定拆分你的data.frame

    dd1 <- df[df$type == "B" ,]  # get all rows of just type A
    dd2 <- df[df$type == "A" ,]  # get all rows of just type B

    v   <- dd2[sample(nrow(dd2), 2), ] #sample two rows at random that are type A
    # if you want to sample 20 rows change the 2 to a 20

    cols <- c("longitude", "latitude")
    dd1[,cols][sample(nrow(dd1), 2), ] <- v[,cols] 
    #Add the random long/lat selected from type As into 2 random long/lat of B


# put the As and Bs back together
rbind(dd2,dd1)
#  type xvar longitude latitude
# 1    A   20    -87.81    40.11
# 2    A   12    -87.82    40.12
# 3    A   50    -87.85    40.22
# 4    B   24    -87.79    40.04
# 5    B   30    -87.85    40.22
# 6    B   12    -87.81    40.11
# 7    B   66    -87.66    40.44

如您所见,B 的第 5 行和第 6 行具有从 A 类型中随机选择的新纬度和经度值。不过,我没有更改 xvar 的值。我不知道你是否想要这个。如果您确实也想更改xvars,那么您可以将cols 更改为cols &lt;- c("xvar","longitude", "latitude")

在函数内部看起来像:

changestuff <-  function(x){

        dd1 <- x[x$type == "B" ,]  # get just A
        dd2 <- x[x$type == "A" ,]  # get just B
        v   <- dd2[sample(nrow(dd2), 2), ]
        cols <- c("longitude", "latitude")
        dd1[,cols][sample(nrow(dd1), 2), ] <- v[,cols] 
        rbind(dd2,dd1)
                            }

changestuff(df)

【讨论】:

  • 您能否为您的答案添加解释?
  • 让我知道你没有得到哪些部分:)
  • 谢谢你,user1317221_G。我不明白为什么你随机抽取两行 A 型。所以,在我的例子中, v
  • 在您的情况下,您会将 2 更改为 20 对吗?选择 A 的 20 个 x,y 值。然后将其他 2 个更改为 20 个,将 A 的选定值变成 B 的 20 个值。
  • 这个答案的更新有很大帮助。当它只是一段代码时,很难阅读。
【解决方案2】:

我认为您正在寻找的功能是“样本”功能。它会像这样工作(使用你的循环方法):

drawn_Sample <- sample(21:25000, 20000, rep=FALSE)
myresult <- integer(1000)    

for (i in seq(1:1000){
index_Values <- (1 + (i-1)*20):(20 + (i-1)*20))
myresult[i] <- myfun(my_Data$xvar[1:20], my_Data$longitude[drawn_Sample[index_Values]], my_Data$latitude[drawn_Sample[index_Values]])
}

在这种情况下,我将 1:20 行(值为“A”的行)随机分配给 21:25000 随机选择的 20 行组,然后将函数应用于各个分组。

这感觉有点不必要的复杂,我认为如果我们对您的函数('myfun')有更多了解,我们可以将其全部压缩。我假设它是矢量化的。

更新:应 OP 的要求,我正在添加如何修改此答案以适应不易排序的数据框。

repetitions <- 1000 # Change this as necessary

A_data <- my_Data[my_Data$type=="A",]
B_data <- my_Data[my_Data$type=="B",]

A_rows <- nrow(A_data)
B_rows <- nrow(B_data)

drawn_Sample <- sample(1:B_rows, repetitions * A_rows, rep=FALSE)
myresult <- integer(repetitions)    

for (i in seq(1:repetitions){
index_Values <- (1 + (i-1)*A_rows):(A_rows + (i-1)*A_rows))
myresult[i] <- myfun(A_data$xvar, B_data$longitude[drawn_Sample[index_Values]], B_data$latitude[drawn_Sample[index_Values]])
}

【讨论】:

  • 非常感谢,Dinre。但我认为你的代码不能解决我的问题。在您的情况下,可以选择原始数据框的第一行。关键是我必须在 type="B" 空间上随机分配 type="A" 的 xvar 的 20 个值。
  • 在更彻底地阅读了您的问题后,我意识到您没有提供完整的解释。我已经更新了我的答案以包含更多可能性,但我仍然不清楚您到底想要什么。
  • 再次感谢您,Dinre。我会测试你的代码,但我猜现在你的代码可以工作了。如果数据不按类型排序,您将如何修改代码?
  • 我会立即将其添加到答案中。替换很容易。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-13
  • 1970-01-01
相关资源
最近更新 更多