使用sapply中的rep根据另一个向量拉伸向量

使用sapply中的rep根据另一个向量拉伸向量,r,apply,sapply,R,Apply,Sapply,我想生成边的data.frame。当多条边在一个节点上结束时会出现问题。边在向量from和to中定义 # Data vertices <- data.frame(id = 1:3, label = c("a", "b", "c"), stringsAsFactors = FALSE) to <- c("a", "b", "c") from1 <- c("c", "a", "b") from2 <- c("c", "a", "a,b,c") 但是,例如,从2开始的尝试失败

我想生成边的
data.frame
。当多条边在一个节点上结束时会出现问题。边在向量
from
to
中定义

# Data
vertices <- data.frame(id = 1:3, label = c("a", "b", "c"), stringsAsFactors = FALSE)
to <- c("a", "b", "c")
from1 <- c("c", "a", "b")
from2 <- c("c", "a", "a,b,c")
但是,例如,从2开始的
尝试失败

因此,我尝试了以下方法:

# Attempt 2
create_edges_2 <- function(from, to) {
  to <- sapply(unlist(sapply(strsplit(to, ","), function(x){vertices$id[vertices$label == x]})), function(x){rep(x, sapply(strsplit(from2, ","), length))})
  from <- unlist(sapply(strsplit(from2, ","), function(x){vertices$id[vertices$label == x]}))
  data.frame(from = from, to = to, stringsAsFactors = FALSE)
}
这里有一个方法:

# Attempt 3
library(dplyr)
to <- sapply(to, function(x){vertices$id[vertices$label == x]})
from0 <- sapply(from2, function(x) strsplit(x, ",")) %>% unlist() %>% as.character()
lengths0 <- lapply(sapply(from2, function(x) strsplit(x, ",")), length) %>% unlist()

to0 <- c()
for( i in 1:length(lengths0)) to0 <- c(to0, rep(to[i], lengths0[i]))

from <- sapply(from0, function(x){vertices$id[vertices$label == x]})
edges <- data.frame(from = from, to = to0, stringsAsFactors = FALSE)
edges

其思想是使用逗号分隔符从
拆分
,并存储每个元素的大小,以便“拉伸”每个节点。这里使用
for
循环来完成

您可以使用连接或
匹配来完成此操作

f2 <- strsplit(from2, ',')

df <- data.frame(from = unlist(f2)
                 , to = rep(to, lengths(f2))
                 , stringsAsFactors = FALSE)
连接

library(dplyr)

df %>% 
  inner_join(vertices, by = c(from = 'label')) %>% 
  inner_join(vertices, by = c(to = 'label')) %>% 
  select_at(vars(matches('.x|.y')))

#   id.x id.y
# 1    3    1
# 2    1    2
# 3    1    3
# 4    2    3
# 5    3    3

感谢您为我指出
length
函数。
rep(to,length(from))
部分是我头脑中缺失的一环
# Attempt 3
library(dplyr)
to <- sapply(to, function(x){vertices$id[vertices$label == x]})
from0 <- sapply(from2, function(x) strsplit(x, ",")) %>% unlist() %>% as.character()
lengths0 <- lapply(sapply(from2, function(x) strsplit(x, ",")), length) %>% unlist()

to0 <- c()
for( i in 1:length(lengths0)) to0 <- c(to0, rep(to[i], lengths0[i]))

from <- sapply(from0, function(x){vertices$id[vertices$label == x]})
edges <- data.frame(from = from, to = to0, stringsAsFactors = FALSE)
edges
  from to
1    3  1
2    1  2
3    1  3
4    2  3
5    3  3
f2 <- strsplit(from2, ',')

df <- data.frame(from = unlist(f2)
                 , to = rep(to, lengths(f2))
                 , stringsAsFactors = FALSE)
library(tidyverse)

map_dfc(df, ~ with(vertices, id[match(.x, label)]))

# # A tibble: 5 x 2
#    from    to
#   <int> <int>
# 1     3     1
# 2     1     2
# 3     1     3
# 4     2     3
# 5     3     3
library(dplyr)

df %>% 
  inner_join(vertices, by = c(from = 'label')) %>% 
  inner_join(vertices, by = c(to = 'label')) %>% 
  select_at(vars(matches('.x|.y')))

#   id.x id.y
# 1    3    1
# 2    1    2
# 3    1    3
# 4    2    3
# 5    3    3