R数据操作

R data manipulations

非常感谢您的帮助...
我有每个国家不同国家和不同地区的东西的高度分布直方图(见table),需要做以下工作:

  1. 将直方图数据转换回“原始”数据向量(即复制 heightcount 次)。例如:
    英格兰北部:12,12,12,12,12,11,11,11,10,8
    英格兰南部:12,12,10,10,7,7,7,7,7
    等等...
  2. 计算 每对 向量之间的 Wasserstein 距离 - transport::wasserstein1d(vectorA, vectorB)
国家 地区 身高 计数
英国 12 5
英国 11 3
英国 10 1
英国 8 1
英国 12 2
英国 10 2
英国 7 5
法国 11 3
法国 10 1
法国 8 1
法国 12 2
法国 11 3
法国 10 1

这是使用 combn -

的方法
library(dplyr)
library(tidyr)

df %>%
  uncount(Count) %>%
  split(.[c('Country', 'Region')]) %>%
  Filter(nrow, .) -> list_df

do.call(rbind, combn(seq_along(list_df), 2, function(x) {
  data.frame(region1 = paste0(list_df[[x[1]]]$Country[1],list_df[[x[1]]]$Region[1]), 
             region2 = paste0(list_df[[x[2]]]$Country[1],list_df[[x[2]]]$Region[1]),
              result = transport::wasserstein1d(list_df[[x[1]]]$Height, 
                                                list_df[[x[2]]]$Height))
}, simplify = FALSE))

#       region1      region2 result
#1   FranceEast Englandnorth  0.900
#2   FranceEast Englandsouth  1.867
#3   FranceEast  FranceSouth  0.967
#4 Englandnorth Englandsouth  2.322
#5 Englandnorth  FranceSouth  0.400
#6 Englandsouth  FranceSouth  2.389

这是我生成距离矩阵的方法:

library(dplyr)

your_data %>%
  mutate(full_region = paste(Country, Region)) %>%
  group_by(full_region) %>%
  summarize(points = list(rep(Height, Count))) %>%
  (\(df) matrix(df$points, dimnames = list(df$full_region))) %>%
  usedist::dist_make(\(a, b) transport::wasserstein1d(a[[1]], b[[1]]))

Returns:

              England north England south France East
England south     2.3222222                          
France East       0.9000000     1.8666667            
France South      0.4000000     2.3888889   0.9666667

使用的数据:

your_data <- structure(list(Country = c("England", "England", "England", "England", "England", "England", "England", "France", "France", "France", "France", "France", "France"), Region = c("north", "north", "north", "north", "south", "south", "south", "East", "East", "East", "South", "South", "South"), Height = c(12L, 11L, 10L, 8L, 12L, 10L, 7L, 11L, 10L, 8L, 12L, 11L, 10L), Count = c(5L, 3L, 1L, 1L, 2L, 2L, 5L, 3L, 1L, 1L, 2L, 3L, 1L)), row.names = c(NA, -13L), class = c("tbl_df", "tbl", "data.frame"))