合并两个数据帧以在 r 中粘贴一个 id 变量
Merging two dataframes to paste an id Variable in r
我有一个 ID 数据集和一个维度数据集。我需要合并这两个以创建一组新的 ID。
我的示例数据集如下所示:
ids.data <- data.frame(id.1=c(1,2),
id.2=c(11,12))
> ids.data
id.1 id.2
1 1 11
2 2 12
dims <- data.frame(dim=c("C","E","D"))
> dims
dim
1 C
2 E
3 D
我需要将这两个结合起来,使每个 ID 具有以下三个 ID:
> ids.data.2
id.1 id.2
1 1_C 11_C
2 1_E 11_E
3 1_D 11_D
4 2_C 12_C
5 2_E 12_E
6 2_D 12_D
有什么想法吗?
谢谢!
我们可以在两个数据集上使用crossing
然后paste
library(dplyr)
library(tidyr)
library(stringr)
crossing(ids.data, dims) %>%
transmute(across(starts_with('id'), ~ str_c(.x, dim, sep = '_')))
-输出
# A tibble: 6 × 2
id.1 id.2
<chr> <chr>
1 1_C 11_C
2 1_D 11_D
3 1_E 11_E
4 2_C 12_C
5 2_D 12_D
6 2_E 12_E
或使用 base R
- 通过使用 outer
扩展 dims
的 'dim' 列来遍历 'ids.data'、paste
的列并将 list
转换为 data.frame
data.frame(lapply(ids.data, \(x) c(t(outer(x, dims$dim,
FUN = paste, sep = "_")))))
id.1 id.2
1 1_C 11_C
2 1_E 11_E
3 1_D 11_D
4 2_C 12_C
5 2_E 12_E
6 2_D 12_D
使用outer
.
f <- Vectorize(\(j, i) paste(ids.data[i, ], dims[j,,drop=F], sep='_'), SIMPLIFY=F)
do.call(c, outer(seq_len(nrow(dims)), seq_len(nrow(ids.data)), f)) |>
matrix(nrow=6, byrow=TRUE) |>
as.data.frame() ## optional
# V1 V2
# 1 1_C 11_C
# 2 1_E 11_E
# 3 1_D 11_D
# 4 2_C 12_C
# 5 2_E 12_E
# 6 2_D 12_D
注:R >= 4.1 使用。
数据:
ids.data <- structure(list(id.1 = c(1, 2), id.2 = c(11, 12)), class = "data.frame", row.names = c(NA,
-2L))
dims <- structure(list(dim = c("C", "E", "D")), class = "data.frame", row.names = c(NA,
-3L))
另一种可能的解决方案,基于 purrr::map_dfc
和 tidyr::expand_grid
:
library(tidyverse)
map_dfc(ids.data, ~ expand_grid(.x, dims$dim) %>% apply(1, str_c, collapse="_"))
#> # A tibble: 6 × 2
#> id.1 id.2
#> <chr> <chr>
#> 1 1_C 11_C
#> 2 1_E 11_E
#> 3 1_D 11_D
#> 4 2_C 12_C
#> 5 2_E 12_E
#> 6 2_D 12_D
我有一个 ID 数据集和一个维度数据集。我需要合并这两个以创建一组新的 ID。
我的示例数据集如下所示:
ids.data <- data.frame(id.1=c(1,2),
id.2=c(11,12))
> ids.data
id.1 id.2
1 1 11
2 2 12
dims <- data.frame(dim=c("C","E","D"))
> dims
dim
1 C
2 E
3 D
我需要将这两个结合起来,使每个 ID 具有以下三个 ID:
> ids.data.2
id.1 id.2
1 1_C 11_C
2 1_E 11_E
3 1_D 11_D
4 2_C 12_C
5 2_E 12_E
6 2_D 12_D
有什么想法吗? 谢谢!
我们可以在两个数据集上使用crossing
然后paste
library(dplyr)
library(tidyr)
library(stringr)
crossing(ids.data, dims) %>%
transmute(across(starts_with('id'), ~ str_c(.x, dim, sep = '_')))
-输出
# A tibble: 6 × 2
id.1 id.2
<chr> <chr>
1 1_C 11_C
2 1_D 11_D
3 1_E 11_E
4 2_C 12_C
5 2_D 12_D
6 2_E 12_E
或使用 base R
- 通过使用 outer
扩展 dims
的 'dim' 列来遍历 'ids.data'、paste
的列并将 list
转换为 data.frame
data.frame(lapply(ids.data, \(x) c(t(outer(x, dims$dim,
FUN = paste, sep = "_")))))
id.1 id.2
1 1_C 11_C
2 1_E 11_E
3 1_D 11_D
4 2_C 12_C
5 2_E 12_E
6 2_D 12_D
使用outer
.
f <- Vectorize(\(j, i) paste(ids.data[i, ], dims[j,,drop=F], sep='_'), SIMPLIFY=F)
do.call(c, outer(seq_len(nrow(dims)), seq_len(nrow(ids.data)), f)) |>
matrix(nrow=6, byrow=TRUE) |>
as.data.frame() ## optional
# V1 V2
# 1 1_C 11_C
# 2 1_E 11_E
# 3 1_D 11_D
# 4 2_C 12_C
# 5 2_E 12_E
# 6 2_D 12_D
注:R >= 4.1 使用。
数据:
ids.data <- structure(list(id.1 = c(1, 2), id.2 = c(11, 12)), class = "data.frame", row.names = c(NA,
-2L))
dims <- structure(list(dim = c("C", "E", "D")), class = "data.frame", row.names = c(NA,
-3L))
另一种可能的解决方案,基于 purrr::map_dfc
和 tidyr::expand_grid
:
library(tidyverse)
map_dfc(ids.data, ~ expand_grid(.x, dims$dim) %>% apply(1, str_c, collapse="_"))
#> # A tibble: 6 × 2
#> id.1 id.2
#> <chr> <chr>
#> 1 1_C 11_C
#> 2 1_E 11_E
#> 3 1_D 11_D
#> 4 2_C 12_C
#> 5 2_E 12_E
#> 6 2_D 12_D