You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何计算R数据框中各行各列的所有组合比率?

问题描述

现有如下结构的DataFrame:

28 Madrid 08 Barcelona 46 Valencia/València 03 Alicante/Alacant 41 Sevilla
2020 143.4846560  128.4231590           54.4870538          37.7936793 37.4922771
2032 125.5210867  113.9580077           56.6657609          40.5967195 39.5353532
2031 123.7643426  112.9806035           56.1167784          40.0735714 39.0574155
2030 122.1152422  112.1129958           55.6022418          39.5934808 38.6074651

需要按行计算所有列组合的比率:例如2020行中28 Madrid与08 Barcelona的比率(1.11728023)、28 Madrid与46 Valencia/València的比率(2.63337153)等,对所有年份行执行相同操作。

预期输出可以是长格式/宽格式DataFrame,或列表形式(示例如下):

2020
         Barcelona    Valencia    Alicante    Sevilla
Madrid     1.11         2.63
Barcelona  x.xxx        x.xxx
Valencia   x.xxx        x.xxx
Alicante
Sevilla

2021
         Barcelona    Valencia    Alicante    Sevilla
Madrid     x.xxx        x.xxx
Barcelona  x.xxx        x.xxx
Valencia   x.xxx        x.xxx
Alicante
Sevilla

数据代码:

df = structure(list(`28 Madrid` = c(143.484656024558, 125.521086677107, 
123.764342599024, 122.115242153178, 120.515657778159, 118.995729690994, 
117.540387783171, 116.134561946176, 114.776099307365, 113.393955069462, 
112.024728067427, 110.633972338945, 107.335771447251, 101.333562513803, 
100.321712370789, 101.540238287695, 100.881459258414, 97.0213586064507, 
92.1407963208957, 92.7113075717435, 91.2667300271439), `08 Barcelona` = c(128.423159002175, 
113.958007702376, 112.980603521678, 112.11299584586, 111.277681259713, 
110.556468923735, 109.912760002968, 109.322872898317, 108.74805590218, 
108.179697523977, 107.591963291971, 107.012840550545, 108.358385953488, 
104.229176220936, 104.227023348291, 100.831943187585, 101.294810806198, 
99.6284873791932, 98.9008164252815, 96.2011141288166, 95.6026155335876
), `46 Valencia/València` = c(54.4870537649372, 56.6657608813826, 
56.1167783569818, 55.6022417948964, 55.1178454498369, 54.6528249585798, 
54.222250429638, 53.815357499788, 53.4149231878722, 53.0295589844693, 
52.6291246725535, 52.2286903606376, 54.5171939819631, 50.6721634385131, 
50.517156608094, 49.171611205151, 49.7658040550906, 48.2308058594132, 
47.6064727924476, 46.5817054135662, 45.2253956473996), `03 Alicante/Alacant` = c(37.7936792778645, 
40.5967194612755, 40.0735714086112, 39.5934808088411, 39.1112373364264, 
38.6785099348399, 38.2522411511875, 37.8561125845611, 37.4621368905793, 
37.0789255598212, 36.7000199743524, 36.3211143888836, 39.5934808088411, 
34.3899876265798, 35.0272379294136, 34.247898032029, 34.12949003657, 
32.6267849305632, 32.7365814354433, 32.0282863353341, 31.3049211267119
), `41 Sevilla` = c(37.4922771076053, 39.535353247434, 39.0574155203086, 
38.6074651375645, 38.1919607171357, 37.7850677872857, 37.3997035838828, 
37.0466324701505, 36.7021728469971, 36.3491017332648, 36.0197122186244, 
35.6989341945628, 38.1123044292814, 34.9346644056911, 33.9981648052427, 
34.0412222581369, 34.7452116129567, 33.027219242479, 32.5062240624595, 
31.8495979058233, 31.5094440279593)), row.names = c("2020", "2032", 
"2031", "2030", "2029", "2028", "2027", "2026", "2025", "2024", 
"2023", "2022", "2021", "2017", "2018", "2019", "2015", "2016", 
"2012", "2014", "2013"), class = "data.frame")
解决方案

方法1:基础R实现(生成列表形式的比率矩阵)

该方法生成一个列表,每个元素对应一年的比率矩阵,矩阵行列使用简化后的城市名称,展示所有两两组合的比率:

# 提取城市名称(去掉前缀数字和空格)
city_names = sub("^\\d+ ", "", colnames(df))

# 按行计算比率矩阵,生成列表
ratio_list = lapply(1:nrow(df), function(i) {
  row_vals = as.numeric(df[i, ])
  # 生成两两比率矩阵
  mat = outer(row_vals, row_vals, "/")
  # 设置行列名称为城市名
  dimnames(mat) = list(city_names, city_names)
  # 可选:保留两位小数
  round(mat, 2)
})

# 设置列表名称为年份
names(ratio_list) = rownames(df)

# 查看2020年的结果
ratio_list[["2020"]]

输出示例(2020年):

Barcelona Valencia Alicante Sevilla
Madrid        1.12     2.63     3.80    3.83
Barcelona     0.89     2.36     3.40    3.43
Valencia      0.43     1.00     1.44    1.45
Alicante      0.27     0.69     1.00     1.01
Sevilla       0.26     0.69     0.99     1.00

方法2:tidyverse实现(长格式/宽格式DataFrame)

如果需要更灵活的结构化输出,可以使用tidyverse工具链:

首先安装并加载包:

install.packages("tidyverse")
library(tidyverse)

长格式输出

适合后续数据分析或可视化:

df_long = df %>%
  rownames_to_column("Year") %>%
  pivot_longer(cols = -Year, names_to = "City1", values_to = "Value1") %>%
  pivot_longer(cols = -c(Year, City1, Value1), names_to = "City2", values_to = "Value2") %>%
  mutate(
    # 提取城市名称
    City1 = str_remove(City1, "^\\d+ "),
    City2 = str_remove(City2, "^\\d+ "),
    # 计算比率
    Ratio = round(Value1 / Value2, 2)
  ) %>%
  select(Year, City1, City2, Ratio)

# 查看前几行
head(df_long)

输出示例:

Year   City1    City2 Ratio
1 2020  Madrid Barcelona  1.12
2 2020  Madrid  Valencia  2.63
3 2020  Madrid  Alicante  3.80
4 2020  Madrid   Sevilla  3.83
5 2020 Barcelona  Madrid  0.89
6 2020 Barcelona Valencia  2.36

宽格式输出

接近矩阵形式的表格,便于直观查看单年份数据:

df_wide = df_long %>%
  pivot_wider(names_from = City2, values_from = Ratio) %>%
  arrange(Year)

# 查看2020年的结果
df_wide %>% filter(Year == "2020")

输出示例:

Year   City1 Barcelona Valencia Alicante Sevilla
1 2020  Madrid      1.12     2.63     3.80    3.83
2 2020 Barcelona     1.00     2.36     3.40    3.43
3 2020  Valencia     0.43     1.00     1.44    1.45
4 2020  Alicante     0.27     0.69     1.00     1.01
5 2020   Sevilla     0.26     0.69     0.99     1.00

内容的提问来源于stack exchange,提问作者user113156

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 04:25:39