如何在不重复变量的情况下合并具有共享案例和变量的两个数据集?

时间:2018-10-22 20:56:26

标签: r join dplyr

假设我有以下两个数据集:

library(tidyverse)

iris1 <- iris %>% 
  as_tibble() %>% 
  mutate(id = row_number(),
         Petal.Length = ifelse(id > 75, NA, Petal.Length),
         Petal.Width = ifelse(id > 75, NA, Petal.Width))

iris2 <- iris %>% 
  as_tibble() %>% 
  mutate(id = row_number()) %>% 
  filter(id > 75) %>% 
  select(id, Petal.Length, Petal.Width)

在这里,我将iris2设置为iris1中缺少的数据。我想使用iris2作为键,将iris1中的数据重新加入id中。我可以使用dplyr::full_join并通过id加入,但实际上我想将Petal.Length中的值集成到变量Petal.Widthiris2中,它们各自在iris1中的变量。

是否有比以下方法更好的解决方案?这里的示例有2个变量(Petal.LengthPetal.Width),但是在我的实际数据集中,这影响了一百多个变量,我不得不认为有比手动劳动更好的方法。 / p>

left_join(iris1, iris2, by = "id") %>% 
  mutate(Petal.Length = ifelse(is.na(Petal.Length.x), Petal.Length.y, Petal.Length.x),
         Petal.Width = ifelse(is.na(Petal.Width.x), Petal.Width.y, Petal.Width.x)) %>% 
  select(-Petal.Length.x, -Petal.Length.y, -Petal.Width.x, -Petal.Width.y)

2 个答案:

答案 0 :(得分:1)

我将您的数据集减少到10行。我还没有考虑到这一点,但这可能行得通。

以下是步骤-1)添加数据框标识符字段tablename 2)使用bind_rows进行联合3)按id分组并首先获得 使用summarize_all()的每一列的非NA值。这意味着您需要按优先顺序绑定表。

iris1 <- head(iris, 10) %>% 
  as_tibble() %>% 
  mutate(id = row_number(),
         Petal.Length = ifelse(id > 7, NA, Petal.Length),
         Petal.Width = ifelse(id > 7, NA, Petal.Width),
         tablename = "table1"
         )

# A tibble: 10 x 7
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species    id tablename
          <dbl>       <dbl>        <dbl>       <dbl> <fct>   <int> <chr>    
 1         5.10        3.50         1.40       0.200 setosa      1 table1   
 2         4.90        3.00         1.40       0.200 setosa      2 table1   
 3         4.70        3.20         1.30       0.200 setosa      3 table1   
 4         4.60        3.10         1.50       0.200 setosa      4 table1   
 5         5.00        3.60         1.40       0.200 setosa      5 table1   
 6         5.40        3.90         1.70       0.400 setosa      6 table1   
 7         4.60        3.40         1.40       0.300 setosa      7 table1   
 8         5.00        3.40        NA         NA     setosa      8 table1   
 9         4.40        2.90        NA         NA     setosa      9 table1   
10         4.90        3.10        NA         NA     setosa     10 table1  

iris2 <- head(iris, 10) %>% 
  as_tibble() %>% 
  mutate(id = row_number(), tablename = "table2") %>% 
  filter(id > 7) %>% 
  select(id, Petal.Length, Petal.Width, tablename)

# A tibble: 3 x 4
     id Petal.Length Petal.Width tablename
  <int>        <dbl>       <dbl> <chr>    
1     8         1.50       0.200 table2   
2     9         1.40       0.200 table2   
3    10         1.50       0.100 table2

combined <- bind_rows(iris1, iris2) %>%
  group_by(id) %>%
  summarize_all(function(x) x[!is.na(x)][1])

# A tibble: 10 x 7
# Groups:   id [10]
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species    id tablename
          <dbl>       <dbl>        <dbl>       <dbl> <fct>   <int> <chr>    
 1         5.10        3.50         1.40       0.200 setosa      1 table1   
 2         4.90        3.00         1.40       0.200 setosa      2 table1   
 3         4.70        3.20         1.30       0.200 setosa      3 table1   
 4         4.60        3.10         1.50       0.200 setosa      4 table1   
 5         5.00        3.60         1.40       0.200 setosa      5 table1   
 6         5.40        3.90         1.70       0.400 setosa      6 table1   
 7         4.60        3.40         1.40       0.300 setosa      7 table1   
 8         5.00        3.40         1.50       0.200 setosa      8 table1   
 9         4.40        2.90         1.40       0.200 setosa      9 table1   
10         4.90        3.10         1.50       0.100 setosa     10 table1

答案 1 :(得分:0)

另一个可能的解决方案,但这是假设在操作之前没有NA案例。基本上,将两个数据文件合并,将它们变长,从变量名中删除“ .x”和“ .y”,并删除NA行,然后将数据散布回其原始形状:

iris1 %>% 
  left_join(iris2, by = "id") %>% 
  gather(key = key, value = value, -id) %>%  
  mutate(key = str_remove(key, "\\.[xy]$")) %>% 
  filter(!is.na(value)) %>% 
  spread(key = key, value = value)