Изменение кадра данных в R для двойных данных

#r #dataframe

Вопрос:

У меня есть фрейм данных, подобный показанному ниже. Каждая пара идентификационных номеров (например, 2891, 2892) соответствует паре близнецов.

     ID zyg.x CDsum
1 2891     2     0            
2 2892     2     5            
3 4000     1     0           
4 4001     1     0            
5 4006     2     0
6 4007     2     3
 

Я хотел бы изменить форму этого фрейма данных, чтобы он выглядел так… Обратите внимание, что значение zyg.x (зиготность) одинаково для каждого близнеца в паре.

            Twin Pair     zyg   CDsumTwin1   CDsumTwin2
1   pair1(2891,2892)       2            0            5
2   pair2(4000,4001)       1            0            0
3   pair3(4006,4007)       2            0            3
 

Любая помощь была бы очень признательна.

Ответ №1:

Данные:

 df <- read.table(text = "    ID zyg.x CDsum
1 2891     2     0            
2 2892     2     5            
3 4000     1     0           
4 4001     1     0            
5 4006     2     0
6 4007     2     3")
 

Расположите по идентификатору и создайте переменную «близнец», чтобы различать двух близнецов в каждой паре

 df<- df %>%
  arrange(ID) %>%
  mutate(twin = rep(c(1, 2),length.out = n()))

df
    ID zyg.x CDsum twin
1 2891     2     0    1
2 2892     2     5    2
3 4000     1     0    1
4 4001     1     0    2
5 4006     2     0    1
6 4007     2     3    2
 

Разделите df на два кадра данных — для twin1 и twin2

 twin1 <- df %>%
  filter(twin == 1) %>%
  select(-twin) %>%
  rename(CDsumTwin1 = CDsum, 
         ID1 = ID)

twin1
   ID1 zyg.x CDsumTwin1
1 2891     2          0
3 4000     1          0
5 4006     2          0

twin2 <- df %>%
  filter(twin == 2) %>%
  select(-twin) %>%
  rename(CDsumTwin2 = CDsum,
         ID2 = ID)

twin2
   ID2 zyg.x CDsumTwin2
2 2892     2          5
4 4001     1          0
6 4007     2          3
 

cbind, объединяйте и переставляйте столбцы:

 twin1 %>% cbind(twin2 %>% select(-zyg.x)) %>%
  mutate(`Twin Pair` = paste0("pair (", ID1, ", ", ID2, ")")) %>%
  select(`Twin Pair`, zyg.x, CDsumTwin1, CDsumTwin2)
    
          Twin Pair zyg.x CDsumTwin1 CDsumTwin2
1 pair (2891, 2892)     2          0          5
3 pair (4000, 4001)     1          0          0
5 pair (4006, 4007)     2          0          3
 

Комментарии:

1. Большое вам спасибо за ваш ответ. При запуске вашего последнего фрагмента кода я получаю следующее: Ошибка: Не удается преобразовать фрейм данных с повторяющимися именами. Как я могу это обойти? Еще раз спасибо.

2. @ericm, код работает хорошо, вы правильно его копируете? Не должно быть повторяющихся имен, так как я удаляюсь zyg.x из фрейма данных twin2 при выполнении cbind

Ответ №2:

Вот как мы могли бы достичь этого dplyr только с помощью:

 library(dplyr)
df %>% 
  mutate(rn = ceiling(row_number()/2)) %>% 
  group_by(rn) %>% 
  mutate(Twin_Pair = paste0(ID, collapse = ","),
         Twin_Pair = paste0("pair",rn, "(",Twin_Pair, ")")) %>% 
  mutate(CDsumTwin1 = first(CDsum),
         CDsumTwin2 = last(CDsum), .keep="unused") %>%  
  slice(2) %>% 
  ungroup() %>% 
  select(Twin_Pair, zyg=zyg.x, CDsumTwin1, CDsumTwin2)
 

выход:

   Twin_Pair          zyg CDsumTwin1 CDsumTwin2
  <chr>            <dbl>      <dbl>      <dbl>
1 pair1(2891,2892)     2          0          5
2 pair2(4000,4001)     1          0          0
3 pair3(4006,4007)     2          0          3