Группировать и сохранять столбцы с одинаковым рисунком - PullRequest
0 голосов
/ 18 апреля 2020

Я пытаюсь выяснить, как сгруппировать по одной переменной и сохранить все остальные переменные, которые имеют такой же шаблон вариаций. Вот пример df, где gp - моя группирующая переменная:

   V1 V2 V3 V4 V5 V6 gp
1  0  1  0  0  0  0  x
2  0  0  0  0  1  0  x
3  1  0  1  0  1  1  y
4  0  0  0  0  0  1  x

Что я хотел бы получить в итоге:

  V1 V3 gp
1  0  0  x
2  0  0  x
3  1  1  y
4  0  0  x

Я пробовал несколько вещей, но ничто, что получит меня, близко к чему-то полезному. Мои реальные данные будут намного больше, но я думаю, что это хорошее место для начала. В этом случае я мог бы сделать что-то числительное c, но мои «настоящие данные» - это данные геномного c, и поэтому их сложнее добавить, чем 0 и 1.

data:

structure(list(V1 = c(0L, 0L, 1L, 0L), V2 = c(1L, 0L, 0L, 0L), 
    V3 = c(0L, 0L, 1L, 0L), V4 = c(0L, 0L, 0L, 0L), V5 = c(0L, 
    1L, 1L, 0L), V6 = c(0L, 0L, 1L, 1L), gp = structure(c(1L, 
    1L, 2L, 1L), .Label = c("x", "y"), class = "factor")), class = "data.frame", row.names = c(NA, 
-4L))

Ответы [ 2 ]

1 голос
/ 18 апреля 2020

Мы можем использовать duplicated, чтобы получить повторяющиеся столбцы. Однако duplicated работает построчно, поэтому мы переносим исходный кадр данных.

t1 <- t(df[-ncol(df)])
df[c(duplicated(t1) | duplicated(t1, fromLast = TRUE), TRUE)]

#  V1 V3 gp
#1  0  0  x
#2  0  0  x
#3  1  1  y
#4  0  0  x

Последний TRUE - это выбор последнего столбца, который gp.

1 голос
/ 18 апреля 2020

Это можно сделать, найдя столбцы с биекцией от gp до значений для этого столбца. То есть для каждого значения в gp (x или y) в столбце переменной есть ровно одно совпадающее значение, например V1 (0 или 1). Обратное также верно, для каждого значения в переменном столбце, например V1, в gp есть ровно одно совпадение.

Чтобы работать со всеми столбцами одновременно, начните с поворота в более длинную форму. Это также сразу удалит легкие дубликаты.

uniq <- df %>% pivot_longer(-gp) %>% distinct(name, gp, value)
#    name  gp    value
#    <chr> <fct> <int>
#  1 V1    x         0
#  2 V2    x         1
#  3 V3    x         0
#  4 V4    x         0
#  5 V5    x         0
#  6 V6    x         0
#  7 V2    x         0
#  8 V5    x         1
# ...
# 14 V6    y         1
# 15 V6    x         1

Затем вы можете найти «ровно один раз» совпадения в одном направлении, посчитав, как часто каждое значение gp отображается за name. Это будет ровно один раз, если оно всегда соответствует постоянному значению для столбца переменной.

match_left <- uniq %>%
  count(name, gp) %>%
  group_by(name) %>%
  filter(max(n) == 1) %>%
  distinct(name)

match_left
# # A tibble: 3 x 1
# # Groups:   name [3]
#   name 
#   <chr>
# 1 V1   
# 2 V3   
# 3 V4   

Сделайте то же самое, но в обратном порядке для столбца значения.

match_right <- uniq %>%
  count(name, value) %>%
  group_by(name) %>%
  filter(max(n) == 1) %>%
  distinct(name)

match_right
# # A tibble: 2 x 1
# # Groups:   name [2]
#   name 
#   <chr>
# 1 V1   
# 2 V3   

Теперь, когда мы знаем, какие переменные оставить, мы можем объединить все вместе и преобразовать в широкую форму.

matches <- df %>%
  mutate(i = row_number()) %>%
  pivot_longer(-c(i, gp)) %>%
  inner_join(match_left, on='name') %>%
  inner_join(match_right, on='name') %>%
  spread(name, value) %>%
  arrange(i) %>%
  select(-i)

matches
# # A tibble: 4 x 3
#   gp       V1    V3
#   <fct> <int> <int>
# 1 x         0     0
# 2 x         0     0
# 3 y         1     1
# 4 x         0     0
...