我有一个演员列表:
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
首先,我想消除边缘列表中的自引用,即我的“边缘”数据帧中的行1,2,5。
non.self.ref <- edge[!(edge$from == edge$to),]
不会产生预期的结果。
其次,edge包含一个不在'actor'数据框中的名称('Frank Smith')。我想在我的'演员'数据框中添加'Frank Smith',即使我没有'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
解决方案,但一般不要在每个问题上提出多个问题。
filter
允许一个非常直观的语法,只是指定你想保持from
不等于to
的行。gather
了from
和to
列,所以所有演员都在一列。然后我们使用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创建于2018-03-02(v0.2.0)。
我发现包括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>