创建唯一的名称列表

Create unique list of names

我有演员名单:

name <- c('John Doe','Peter Gynn','Jolie Hope')
age <- c(26 , 32, 56)
postcode <- c('4011', '5600', '7700')
actors <- data.frame(name, age, postcode)

        name age postcode
1   John Doe  26     4011
2 Peter Gynn  32     5600
3 Jolie Hope  56     7700

我还有一个边关系列表:

from <- c('John Doe','John Doe','John Doe', 'Peter Gynn', 'Peter Gynn', 'Jolie Hope')
to <- c('John Doe', 'John Doe', 'Peter Gynn', 'Jolie Hope', 'Peter Gynn', 'Frank Smith')
edge <- data.frame(from, to)

        from          to
1   John Doe    John Doe
2   John Doe    John Doe
3   John Doe  Peter Gynn
4 Peter Gynn  Jolie Hope
5 Peter Gynn  Peter Gynn
6 Jolie Hope Frank Smith

首先,我想消除边缘列表中的自引用,即 'edge' 数据框中的第 1、2、5 行。

non.self.ref <- edge[!(edge$from == edge$to),]

没有产生预期的结果。

其次,edge 包含一个不在 'actor' 数据帧中的名称 ('Frank Smith')。我想将 'Frank Smith' 添加到我的 'actor' 数据框,即使我没有 'Frank Smith' 的年龄或邮政编码数据。例如:

         name age postcode
1    John Doe  26     4011
2  Peter Gynn  32     5600
3  Jolie Hope  56     7700
4 Frank Smith  NA       NA

我将不胜感激一个整洁的解决方案!

这是两个部分的 tidyverse 解决方案,但一般来说每个问题不要问多个问题。

  1. 第一部分相当简单。 filter 允许使用非常直观的语法,仅指定您要保留 from 不等于 to.
  2. 的行
  3. 第二部分有点复杂。首先,我们 gather 向上 fromto 列,因此所有演员都在一列中。然后我们使用 distinct 为我们留下一个具有唯一演员姓名的单列 tbl。最后,我们可以使用 full_join 来合并表格。 full_join 保留两个表中的所有行和列,默认匹配共享名称列,如果没有数据则填充 NA(因为 Frank 没有)。
library(tidyverse)
actors <- tibble(
  name = c('John Doe','Peter Gynn','Jolie Hope'),
  age = c(26 , 32, 56),
  postcode = c('4011', '5600', '7700')
  )
edge <- tibble(
  from = c('John Doe','John Doe','John Doe', 'Peter Gynn', 'Peter Gynn', 'Jolie Hope'),
  to = c('John Doe', 'John Doe', 'Peter Gynn', 'Jolie Hope', 'Peter Gynn', 'Frank Smith')
)

edge %>%
  filter(from != to)
#> # A tibble: 3 x 2
#>   from       to         
#>   <chr>      <chr>      
#> 1 John Doe   Peter Gynn 
#> 2 Peter Gynn Jolie Hope 
#> 3 Jolie Hope Frank Smith

edge %>%
  gather("to_from", "name", from, to) %>%
  distinct(name) %>%
  full_join(actors)
#> Joining, by = "name"
#> # A tibble: 4 x 3
#>   name          age postcode
#>   <chr>       <dbl> <chr>   
#> 1 John Doe     26.0 4011    
#> 2 Peter Gynn   32.0 5600    
#> 3 Jolie Hope   56.0 7700    
#> 4 Frank Smith  NA   <NA>

reprex package (v0.2.0) 创建于 2018-03-02。

我发现包括 stringsAsFactors = FALSE 例如

edge <- data.frame(from, to, stringsAsFactors = F)

然后:

non.self.ref <- edge[!(edge$from == edge$to),]

有效!

带有 dplyr 的选项是通过比较 'from' 和 'to' 来 filter 行(以获得第一个输出 - 如果我们需要,则不需要只对第二个输出感兴趣),unlist,获取 unique 值,将其转换为 tibble 并执行 left_join

library(dplyr)
edge %>%
  filter(from != to) %>% #get the results for the first question
  unlist %>%
  unique %>% 
  tibble(name = .) %>% 
  left_join(actors) # second output
# A tibble: 4 x 3
#   name          age postcode
#   <chr>       <dbl> <fctr>  
#1 John Doe     26.0 4011    
#2 Peter Gynn   32.0 5600    
#3 Jolie Hope   56.0 7700    
#4 Frank Smith  NA   <NA>