Как объединить два набора данных с общими делами и переменными без дублирования переменных? - PullRequest
0 голосов
/ 22 октября 2018

Предположим, у меня есть два следующих набора данных:

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.Width, когда на самом деле я хочу, чтобы значения в iris2 были интегрированы в соответствующие им переменные в iris1.

Есть ли более элегантное решение, чем приведенное ниже?Пример здесь с 2 переменными (Petal.Length и Petal.Width), но в моем фактическом наборе данных это влияет на сотню переменных, и я должен был бы думать, что есть лучший способ, чем с помощью ручного труда.

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 голосов
/ 23 октября 2018

Другое потенциальное решение, но оно предполагает, что до манипуляции не было случаев НС.По сути, объедините два файла данных, превратите их в long, удалите «.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)
0 голосов
/ 23 октября 2018

Я сократил ваш набор данных до 10 строк.Я не продумал это, но это может сработать.

Вот шаги - 1) добавили поле идентификатора кадра данных tablename 2) сделали объединение, используя bind_rows 3), сгруппированные по id иполучил first non-NA значение для каждого столбца, используя summarize_all().Это означает, что вам нужно связывать таблицы в порядке предпочтения.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...