首页 > 解决方案 > 基于另一个数据帧更新 R 中的数据帧

问题描述

编辑

我有一个数据框t

> t
       v     w  e
1   dave  adam ->
2 floria  adam ->
3 floria  dave ->
4 floria quinn ->
5  quinn  adam ->

和另一个数据框data

> data
      v      w   e
1  dave floria  ->
2 quinn   adam <->

我想t根据 dataframe更新 dataframe 中的列 e data

可能存在 v 和 w in 与 v 和 w int相同data但交换的情况。戴夫和弗洛里亚就是这种情况。在t中,dave 在 w 中,而 floria 在 v 中;而在 中data,dave 在 v 中,而 floria 在 w 中。只要名称以任何顺序在 v 和 w 中,我就想更改 e。

我的预期输出是:

       v     w   e
1   dave  adam  ->
2 floria  adam  ->
3 floria  dave  <-
4 floria quinn  ->
5  quinn  adam <->

数据框的第一行data显示 Dave -> Floria,第二行显示 Quinn <-> Adam。这就是为什么在预期输出中,第 3 行中的箭头指向 floria 而第 5 行中的箭头是双向的。

我该如何在 dplyr 中做到这一点?

标签: rdplyr

解决方案


您可以尝试使用intersect

t %>%
  rowwise %>%
  mutate(flag = (v %in% V & w %in% W) & (match(w,W) == match(v,V)) | (v %in% W & w %in% V) & (match(w,V) == match(v,W)),
              txt = ifelse(flag, paste(intersect(v,c(V,W)),E,intersect(w,c(V,W))), paste(v,e,w)))

  v      w     e     flag  txt            
  <chr>  <chr> <chr> <lgl> <chr>          
1 dave   adam  ->    FALSE dave -> adam   
2 floria adam  ->    FALSE floria -> adam 
3 floria dave  ->    TRUE  floria <-> dave
4 floria quinn ->    FALSE floria -> quinn
5 quinn  adam  ->    TRUE  quinn <-> adam 

编辑

t <- read.table(text = "       v     w  e
   dave  adam '<-'
 floria  adam '->'
 floria  dave '<-'
 floria quinn '->'
  quinn  adam '->' ", header = T)
t

       v     w  e
1   dave  adam <-
2 floria  adam ->
3 floria  dave <-
4 floria quinn ->
5  quinn  adam ->

V <- c('dave', 'quinn')
W <- c('floria', 'adam')
E <- c('<-', '<->')
t %>%
  rowwise %>%
  mutate(flag = (v %in% V & w %in% W) & (match(w,W) == match(v,V)) | (v %in% W & w %in% V) & (match(w,V) == match(v,W)),
         txt = case_when(
           flag & (e %in% E) ~ paste(intersect(v,c(V,W)),intersect(E,e),intersect(w,c(V,W))),
           flag ~ paste(intersect(v,c(V,W)),"<->",intersect(w,c(V,W))),
           TRUE ~ paste(v,e,w)
         ))

  v      w     e     flag  txt            
  <chr>  <chr> <chr> <lgl> <chr>          
1 dave   adam  <-    FALSE dave <- adam   
2 floria adam  ->    FALSE floria -> adam 
3 floria dave  <-    TRUE  floria <- dave 
4 floria quinn ->    FALSE floria -> quinn
5 quinn  adam  ->    TRUE  quinn <-> adam 

编辑 2

这有点乱,但你可以试试。

t %>%
  rowwise %>%
  mutate(key = paste0(v,w),
         #key2 = paste0(w,v),
         key1 = match(key, data2$key1),
         key2 = match(key, data2$key2)
         ) %>%
  mutate(e = case_when(
    is.na(key1) & is.na(key2) ~ e,
    !is.na(key1) & data2$e[key1] == "<->" ~ "<->",
    !is.na(key1) & data2$e[key1] == "->" ~ "->",
    !is.na(key1) & data2$e[key1] == "<-" ~ "<-",
    data2$e[key2] == "<->" ~ "<->",
    data2$e[key2] == "->" ~ "<-",
    data2$e[key2] == "<-" ~ "<->",
    TRUE ~ e
  )) %>%
  select(-key, -key1, -key2)

  v      w     e    
  <chr>  <chr> <chr>
1 dave   adam  ->   
2 floria adam  ->   
3 floria dave  <-   
4 floria quinn ->   
5 quinn  adam  <->  

推荐阅读