将多个值传播到 R 中数据框中的唯一值
Spread multiple values to unique values in data frame in R
假设我有一个包含姓名列表的数据框:
> x <- c("a", "b", "c")
> x <- as.data.frame(x)
# > x
# 1 a
# 2 b
# 3 c
我想将每个唯一名称(x,下方)传播到每个名称(y,下方)并在原始列之前创建一个新列,以便新数据框如下所示:
# > z
# x y
# a a
# a b
# a c
# b a
# b b
# b c
# c a
# c b
# c c
这是为了在网络已满的 igraph 中创建“从”“到”边列表。
我该怎么做?有没有我缺少的简单的 tidyverse 解决方案?
使用 dplyr
和 tidyr
,您可以:
x %>%
mutate(y = x) %>%
complete(y, x)
y x
<fct> <fct>
1 a a
2 a b
3 a c
4 b a
5 b b
6 b c
7 c a
8 c b
9 c c
您可以使用 tidyr::expand_grid
或 tidyr::crossing
tidyr::expand_grid(a = x$x, b = x$x)
#tidyr::crossing(a = x$x, b = x$x)
# a b
# <chr> <chr>
#1 a a
#2 a b
#3 a c
#4 b a
#5 b b
#6 b c
#7 c a
#8 c b
#9 c c
这与基本 R 相似 expand.grid
只是顺序不同。
expand.grid(a = x$x, b = x$x)
基础 R 解决方案:
names <- c("a", "b", "c")
x = rep(names, each=length(names))
y = rep(names, length(names))
df = data.frame(x,y)
df
x y
1 a a
2 a b
3 a c
4 b a
5 b b
6 b c
7 c a
8 c b
9 c c
您还可以使用 expand
函数来 return 两列的所有可能组合:
library(tidyr)
x %>%
mutate(y = x) %>%
expand(x, y)
# A tibble: 9 x 2
x y
<chr> <chr>
1 a a
2 a b
3 a c
4 b a
5 b b
6 b c
7 c a
8 c b
9 c c
您还可以使用crossing
函数:
x <- c("a", "b", "c")
x <- as.data.frame(x)
x$y <- c("a", "b", "c")
crossing(x$x, x$y) # But you can't just use it within a pipeline since the first argument is not data
# A tibble: 9 x 2
`x$x` `x$y`
<chr> <chr>
1 a a
2 a b
3 a c
4 b a
5 b b
6 b c
7 c a
8 c b
9 c c
如果你真的想使用igraph
,这里可能是一个选择
make_full_graph(
length(x),
directed = TRUE,
loops = TRUE
) %>%
set_vertex_attr(name = "name", value = x) %>%
get.data.frame()
这给出了
from to
1 a a
2 a b
3 a c
4 b a
5 b b
6 b c
7 c a
8 c b
9 c c
假设我有一个包含姓名列表的数据框:
> x <- c("a", "b", "c")
> x <- as.data.frame(x)
# > x
# 1 a
# 2 b
# 3 c
我想将每个唯一名称(x,下方)传播到每个名称(y,下方)并在原始列之前创建一个新列,以便新数据框如下所示:
# > z
# x y
# a a
# a b
# a c
# b a
# b b
# b c
# c a
# c b
# c c
这是为了在网络已满的 igraph 中创建“从”“到”边列表。
我该怎么做?有没有我缺少的简单的 tidyverse 解决方案?
使用 dplyr
和 tidyr
,您可以:
x %>%
mutate(y = x) %>%
complete(y, x)
y x
<fct> <fct>
1 a a
2 a b
3 a c
4 b a
5 b b
6 b c
7 c a
8 c b
9 c c
您可以使用 tidyr::expand_grid
或 tidyr::crossing
tidyr::expand_grid(a = x$x, b = x$x)
#tidyr::crossing(a = x$x, b = x$x)
# a b
# <chr> <chr>
#1 a a
#2 a b
#3 a c
#4 b a
#5 b b
#6 b c
#7 c a
#8 c b
#9 c c
这与基本 R 相似 expand.grid
只是顺序不同。
expand.grid(a = x$x, b = x$x)
基础 R 解决方案:
names <- c("a", "b", "c")
x = rep(names, each=length(names))
y = rep(names, length(names))
df = data.frame(x,y)
df
x y
1 a a
2 a b
3 a c
4 b a
5 b b
6 b c
7 c a
8 c b
9 c c
您还可以使用 expand
函数来 return 两列的所有可能组合:
library(tidyr)
x %>%
mutate(y = x) %>%
expand(x, y)
# A tibble: 9 x 2
x y
<chr> <chr>
1 a a
2 a b
3 a c
4 b a
5 b b
6 b c
7 c a
8 c b
9 c c
您还可以使用crossing
函数:
x <- c("a", "b", "c")
x <- as.data.frame(x)
x$y <- c("a", "b", "c")
crossing(x$x, x$y) # But you can't just use it within a pipeline since the first argument is not data
# A tibble: 9 x 2
`x$x` `x$y`
<chr> <chr>
1 a a
2 a b
3 a c
4 b a
5 b b
6 b c
7 c a
8 c b
9 c c
如果你真的想使用igraph
,这里可能是一个选择
make_full_graph(
length(x),
directed = TRUE,
loops = TRUE
) %>%
set_vertex_attr(name = "name", value = x) %>%
get.data.frame()
这给出了
from to
1 a a
2 a b
3 a c
4 b a
5 b b
6 b c
7 c a
8 c b
9 c c