【问题标题】:R: sampling from a dataset based on a certain distribution centered around points in a different datasetR:基于以不同数据集中的点为中心的特定分布从数据集中采样
【发布时间】:2018-07-24 08:19:49
【问题描述】:

我正在尝试根据 X-Y 平面上点的分布从 X-Y-Z 空间中的一组点 df_map 中采样行。分布的均值和标准差在另一个数据集 df_pts 中。

我的数据是这样的

> df_map
   X  Y   Z
A  6  0 103
B -4  2 102
C -2 15 112
D 13  6 105
E  1 -3 117
F  5 16 105
G 10  5 103
H 14 -7 119
I  8 14 107
J -8 -4 100

> df_pts
    x   y   accuracy
a   5  18 -0.8464018
b   3   2  0.5695678
c -18  14 -0.4711559
d  11  13 -0.7306417
e  -3 -10  2.1887011
f  -9 -11  2.1523923
g   5   1 -0.9612284
h  12 -19 -0.4750582
i -16  20 -1.4554292
j   0  -8  3.4028887

我想遍历 df_pts 中的行并根据与(df_pts[i, x], df_pts[i, y]) 的距离的高斯分布从 df_map 中选择一行,其中 2d 标准偏差为df_pts[i, accuracy]。换句话说,在每个i = 1:10,我想根据平均值df_pts[i, x]^2 + df_pts[i, y]^2和2d sddf_pts[i, accuracy]的正态分布从df_map中抽取一个样本。

如果您有任何关于高效且复杂的方法的建议,我将不胜感激。我对 R 比较陌生,并且来自 C 背景,我编写这样的任务的方式涉及太多的基本循环和使用基本操作的每一步计算,这使得代码非常慢。

如果问题太琐碎或结构不合理,我提前道歉。

【问题讨论】:

    标签: r sampling


    【解决方案1】:

    易于使用的数据:

    df_map <- data.frame(x = c(6,-4,-2,13,1,5,10,14,8,-8),
                         y= c(0,2,15,6,-3,16,5,-7,14,-4),
                         z= c(103,102,112,105,117,105,103,119,107,100))
    df_pts <- data.frame(x = c(5,3,-18,11,-3,-9,5,12,-16,0),
                  y= c(18,2,14,13,-10,-11,1,-19,20,-8),
                  accuracy = c(-0.8464018, 0.5695678,-0.4711559,-0.7306417, 2.1887011, 2.1523923,-0.9612284,-0.4750582,-1.4554292,3.4028887))
    

    我认为您正在寻找的是最近邻搜索。过去我为此苦苦挣扎,但这是我想出的代码:

    library("FNN")
    
    findNeighbour <- function(index){
      first = df_pts[index,1:2]
      hit = get.knnx(df_map[c("x","y")], first, k =1 )
      hit_index = hit[[1]]
      hit_result = df_map[hit_index,]
      result = append(df_pts[index,], hit_result)
    }
    t <- do.call(rbind, lapply(1:nrow(df_map),findNeighbour))
    

    导致:

         x   y   accuracy x.1 y.1   z
    1    5  18 -0.8464018   5  16 105
    2    3   2  0.5695678   6   0 103
    3  -18  14 -0.4711559  -2  15 112
    4   11  13 -0.7306417   8  14 107
    5   -3 -10  2.1887011  -8  -4 100
    6   -9 -11  2.1523923  -8  -4 100
    7    5   1 -0.9612284   6   0 103
    8   12 -19 -0.4750582  14  -7 119
    9  -16  20 -1.4554292  -2  15 112
    10   0  -8  3.4028887   1  -3 117
    

    正如您所见,在此示例中,某些数据被多次匹配,因此根据您的目标,您可能希望将这些数据丢弃或进行双向搜索。

    我希望这就是你要找的东西

    【讨论】:

    • 非常感谢您的建议。我实际上已经编写了一个函数来完成 get.knnx 自己所做的事情,但是 get.knnx 做得更有效,代码看起来也更好。谢谢!但是,这是选择最近的邻居。我想将其更改为从 df_map 中选择 df_map[i,],概率为 p(i),其中 p(i) = f(distance of (df_map[i, X], df_map[i, Y]) from (df_pts[ i, x], df_pts[i, y])) 和 f 是高斯分布的概率密度函数,均值为 df_pts[i, x]^2 + df_pts[i, y]^2 和 2d 标准差 df_pts[i,准确性]。
    • 我想要做的基本上是 sample(df_map, 1, prob = pdf_df_map, replace = T) pdf_df_map 是具有 (df_map[i, X], df_map[i, Y ]) 如果 (df_pts[i, x], df_pts[i, y]) 周围的点分布是正常的,具有 2d 标准偏差 df_pts[i, accuracy]
    【解决方案2】:

    感谢您的建议。

    我最终做了以下事情

    df_map <- data.frame(X = c(6,-4,-2,13,1,5,10,14,8,-8),
                         Y= c(0,2,15,6,-3,16,5,-7,14,-4),
                         Z= c(103,102,112,105,117,105,103,119,107,100))
    df_pts <- data.frame(x = c(5,3,-18,11,-3,-9,5,12,-16,0),
                         y= c(18,2,14,13,-10,-11,1,-19,20,-8),
                         accuracy = c(-0.8464018, 0.5695678,-0.4711559,-0.7306417, 2.1887011, 2.1523923,-0.9612284,-0.4750582,-1.4554292,3.4028887))
    
    map.point2map <- function(map_in, pt_in) {
      dists <- dist(rbind(cbind(x = pt_in['x'],
                               y = pt_in['y']),
                         cbind(x = map_in$X,
                               y = map_in$Y)))[1:dim(map_in)[1]]
    
      mu <- mean(dists)
      stddev <- abs(as.numeric(pt_in['accuracy']))
    
      return(sample_n(tbl = map_in[, c('X', 'Y')],
                      size = 1,
                      replace = TRUE,
                      weight = dnorm(dists, mean = mu, sd = stddev)))
    }
    
    mapped <- apply(df_pts,
                    1,
                    function(x) map.point2map(map_in = df_map,
                                              pt_in = x))
    

    并且 mapped 是根据需要从 df_map 采样的 10 个点的列表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-27
      • 2017-05-20
      • 2020-11-10
      • 1970-01-01
      • 2021-08-08
      • 2019-11-18
      • 2018-05-01
      相关资源
      最近更新 更多