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

如何利用rep()处理data.frame或向量,生成指定关联数据组合?

问题描述

我有一个data.frame列表dflist,结构如下:

dflist:
[[12]]
label         site
   <chr>        <int>
 [1] NODE_0000138    12
 [2] NODE_0000222    12
 [3] NODE_0000205    12
 [4] NODE_0000241    12
 [5] 061D03KR01      12
 [6] 061D03KR03      12

[[15]]
label         site
  <chr>        <int>
[1] NODE_0000203    15
[2] 061D03OR17      15
[3] 061D03OR19      15
[4] 061D03UR28      15

[[18]]
label         site
   <chr>        <int>
 [1] NODE_0000181    18
 [2] NODE_0000226    18
 [3] 061D03KR11      18
 [4] 061D03OR02      18
 [5] 061D03OR32      18

同时有一个记录关联关系的data.frame df:

df
  from to
1   12 18
2   12 35
3   15 18

需求是生成一个新的data.frame,根据df的每一行,生成from对应的dflist元素与to对应的dflist元素的所有可能组合。比如df第一行12对应18,要生成所有12组内label+site和18组内label+site的笛卡尔积组合,以此类推处理df所有行。试了for循环太繁琐,rep系列函数也没实现想要的重复次数,求更优方法。

解决方案

方法1:tidyverse工具链实现

加载dplyr和purrr,通过遍历关联关系行,生成笛卡尔积后合并结果:

library(dplyr)
library(purrr)

# 给dflist元素命名,确保能通过site值索引
names(dflist) <- names(dflist) %>% replace(is.na(.), as.integer(which(is.na(.))))

# 遍历df每一行生成组合并合并
result <- pmap_dfr(df, function(from, to) {
  df_from <- dflist[[as.character(from)]]
  df_to <- dflist[[as.character(to)]]
  
  # 跳过不存在的to对应的列表元素(比如示例中的35)
  if (is.null(df_to)) return(tibble())
  
  # 生成笛卡尔积并重命名列避免冲突
  df_from %>%
    rename(from_label = label, from_site = site) %>%
    crossing(df_to %>% rename(to_label = label, to_site = site))
})

方法2:data.table高效实现

适合处理大数据量,利用CJ函数快速生成笛卡尔积:

library(data.table)

# 给dflist元素命名
names(dflist) <- as.character(names(dflist)) %>% replace(is.na(.), as.integer(which(is.na(.))))

dt <- as.data.table(df)

# 按关联关系分组生成组合,合并结果
result <- rbindlist(dt[, {
  df_from <- dflist[[as.character(from)]]
  df_to <- dflist[[as.character(to)]]
  if (is.null(df_to)) return(NULL)
  CJ(df_from, df_to, sorted = FALSE) %>% setnames(c("from_label", "from_site", "to_label", "to_site"))
}, by = .(from, to)]$V1)

方法3:基础R原生实现

无需加载第三方包,用expand.grid生成笛卡尔积:

# 给dflist元素命名
names(dflist) <- as.character(names(dflist)) %>% replace(is.na(.), as.integer(which(is.na(.))))

# 遍历生成每个关联关系的组合列表
result_list <- lapply(1:nrow(df), function(i) {
  from_val <- df$from[i]
  to_val <- df$to[i]
  
  df_from <- dflist[[as.character(from_val)]]
  df_to <- dflist[[as.character(to_val)]]
  
  if (is.null(df_to)) return(NULL)
  
  expand.grid(df_from, df_to, stringsAsFactors = FALSE) %>%
    setNames(c("from_label", "from_site", "to_label", "to_site"))
})

# 合并所有非空结果
result <- do.call(rbind, Filter(Negate(is.null), result_list))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 17:14:51