Я использовал ответ Флориана на этот вопрос, чтобы получить уникальные пары отдельно для одной общей (группирующей) переменной. Можно ли распространить это на случай, когда есть две группирующие переменные, и пары должны быть уникальными на основе любой группирующей переменной?
Например, если входные данные
df = data.frame(scaffold = c("A", "A", "B", "B", "B", "C", "C", "D","A"),
geneID = c("162", "276", "64", "276", "281", "64", "162", "162","64"),
Grouping2 = c("x1", "x2", "x3", "x1", "x2", "x3", "x1", "x2", "x3"),
stringsAsFactors = F)
и мои группы — geneID
и Grouping2
, как мне создать все наборы уникальных пар для scaffold
? В этом игрушечном примере A
и B
пары как на 276
, так и на x1
, но должна быть создана только одна пара A-B?
Измените, чтобы добавить реальный пример:
В моем наборе данных 25 530 человек. Хотя некоторые люди живут одни, более половины живут в семьях (Household
), состоящих как минимум из двух человек. Люди также работают/ходят в школу (Work
). Каждый человек — это один ряд. Мне нужно найти все уникальные пары людей, имеющие одинаковый Household
номер или одинаковое Work
имя.
Например, если люди A, B и C живут в 123 Any Street
, то пары на основе домохозяйств — это A-B, A-C и B-C. Если B и C оба работают в XYZ Tailoring
, где также работают D, E и F, то пары на основе компаний: B-D, B-E, B-F, C-D, CE, C-F, DE, D-F и E-F. Не существует пары BC, основанной на XYZ Tailoring
, поскольку она уже учтена в комбинации 123 Any Street
.
Данные игрушки:
temp <- data.frame(Person = c("A", "B", "C", "D", "E", "F"),
Household = c("123 Any Street", "123 Any Street", "123 Any Street", "4 Second Street", "5 Third Street",
"6 Last Street"),
Work = c("One Company", "XYZ Tailoring", "XYZ Tailoring", "XYZ Tailoring", "XYZ Tailoring",
"XYZ Tailoring"))
И это моя проблема. Чтобы получить целый набор уникальных пар, поделившись Household
или Work
.
Редактировать 2: желаемый результат. Кадр данных с двумя переменными (или что-то, что я могу превратить в фрейм данных с двумя переменными, например, матрицу). Вызвав переменные from
и to
, вы получите 12 уникальных пар. Порядок их не имеет значения.
to from
A B
A C
B C
B D
B E
B F
C D
C E
C F
D E
D F
E F
B
и C
связаны как переменной Household
, так и переменной Work
. У меня может быть только одна пара B
и C
, не важно, пары они из Household
или пары из Work
. Пара C
и B
не может возникнуть, так как она является зеркальным отражением B
и C
и, следовательно, является дубликатом.
Вариант tidyverse
:
library(dplyr)
library(tidyr)
library(purrr)
df <- data.frame(scaffold = c("A", "A", "B", "B", "B", "C", "C", "D","A"),
geneID = c("162", "276", "64", "276", "281", "64", "162", "162","64"),
Grouping2 = c("x1", "x2", "x3", "x1", "x2", "x3", "x1", "x2", "x3"),
stringsAsFactors = FALSE)
# summarise() scaffolds as lists, filter() non-matched scaffold values,
# map() unique pairs using combn(), unnest() pairs to individual rows,
# unnest_wider() to individual columns
result <- df |>
summarise(scaffolds = list(unique(scaffold)), .by = c(geneID, Grouping2)) |>
filter(lengths(scaffolds) > 1) |>
mutate(pairs = map(scaffolds, ~ combn(.x, 2, simplify = FALSE))) |>
unnest(pairs) |>
unnest_wider(pairs, names_sep = "_")
data.frame(result)
# geneID Grouping2 scaffolds pairs_1 pairs_2
# 1 162 x1 A, C A C
# 2 64 x3 B, C, A B C
# 3 64 x3 B, C, A B A
# 4 64 x3 B, C, A C A
На основе обновленного набора данных и желаемого результата вы можете использовать pivot_longer()
, чтобы получить перестановки группирующих переменных, суммировать, как и раньше, использовать separate()
для разделения пар и присвоения имен столбцов, а затем возвращать только distinct()
строк:
temp <- data.frame(Person = c("A", "B", "C", "D", "E", "F"),
Household = c("123 Any Street", "123 Any Street", "123 Any Street", "4 Second Street", "5 Third Street",
"6 Last Street"),
Work = c("One Company", "XYZ Tailoring", "XYZ Tailoring", "XYZ Tailoring", "XYZ Tailoring",
"XYZ Tailoring"))
result <- temp |>
pivot_longer(-Person) |>
summarise(tmp = list(unique(Person)), .by = c(name, value)) |>
filter(lengths(tmp) > 1) |>
mutate(pairs = map(tmp, ~ combn(.x, 2, simplify = FALSE))) |>
unnest(pairs) |>
mutate(pairs = map_chr(pairs, ~ paste(sort(.x), collapse = "-"))) |>
separate(pairs, into = c("to", "from"), sep = "-") |>
select("to", "from") |>
distinct()
result
# # A tibble: 12 × 2
# to from
# <chr> <chr>
# 1 A B
# 2 A C
# 3 B C
# 4 B D
# 5 B E
# 6 B F
# 7 C D
# 8 C E
# 9 C F
# 10 D E
# 11 D F
# 12 E F
И разбить каждую половину пары на две переменные, например. Scaffold1, Scaffold2 вместо того, чтобы иметь пару в одной переменной (пары)? Например. Scaffold1 = A, B, A, A и Scaffold2 = C, C, B, C
@Michelle — обновлено с помощью unnest_wider()
для разделения столбца пар. Надеюсь это поможет.
Я использовал этот метод для своих данных, а затем понял, что он не работает для моих данных. Здесь я не хочу, чтобы Grouping2 была вложена в GeneID, а чтобы ссылки были основаны на OR. Пример с игрушкой, возможно, слишком игрушечный. Обновлю свой вопрос.
Это выглядит великолепно, спасибо! Более 774 000 уникальных пар.
Я думаю, вам будет легче помочь, если вы включите ожидаемый результат. Возможно, я что-то упускаю, но мне сложно понять, как должен выглядеть результат. Спасибо.