Функция для создания матрицы, заполненной счетчиком раз, когда число появляется в таблице, но только если другой столбец уникален - PullRequest
0 голосов
/ 05 марта 2020

Это может быть сложный вопрос. У меня есть фрейм данных X со столбцами частица, источник и приемник. Моя цель состоит в том, чтобы создать матрицу, в которой строки - это номера источников, а столбцы - номера приемников. Матрица должна быть заполнена счетчиком количества появлений номера раковины на номер источника, если номер частицы уникален для этой комбинации источник / раковина.

Фрейм данных выглядит следующим образом: Фрейм данных X

Ожидаемый результат должен выглядеть следующим образом: Ожидаемый результат

Вы Можно видеть, что частица 1 из источника 1 находится в приемнике 1 дважды, но считается только один раз. Однако частица 1 из источника 1 находится в приемнике 4, поэтому она также учитывается в столбце 4. Если частица встречается в одной и той же комбинации источник / приемник более одного раза, она считается только один раз. Однако, если частица обнаружена в нескольких приемниках из одного и того же источника, она все равно считается.

Я честно пытался использовать уникальную функцию, но столкнулся с большими трудностями при получении правильного вычисления. Я хотел бы создать функцию для этого.

Я добавил еще один пример, где я добавил строку. Выделенные значения в кадре данных X приведут к выделенному значению в новой матрице. Идея здесь состоит в том, что, поскольку номер частицы отличается, он добавляет единицу, но номер частицы 1 появляется дважды в приемнике 1, поэтому он не учитывается дважды. New_Example

Новая матрица Кроме того, чтобы не считать частицы дважды, если она находится в одном и том же приемнике, мне нужно посчитать, сколько раз частица от одного и того же источник попадает в приемник, если номер частицы уникален.

1 Ответ

1 голос
/ 05 марта 2020

Основа c R подход:

mat <- matrix(rep(0, 64), ncol = 8)
mat[as.matrix(df)] <- 1

Выход

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,]    1    0    0    1    0    0    0    0
[2,]    1    0    1    0    0    1    0    0
[3,]    0    0    1    1    0    0    1    0
[4,]    0    0    0    1    1    1    0    0
[5,]    0    0    1    1    0    0    1    0
[6,]    0    0    1    0    0    0    0    1
[7,]    1    0    1    0    1    0    0    0
[8,]    0    0    0    0    1    0    0    0

Или с tidyverse:

library(tidyverse)

df$unique = 1

expand.grid(source = 1:8, sink = 1:8) %>%
  left_join(distinct(df)) %>%
  replace_na(list(unique = 0)) %>%
  pivot_wider(id_cols = source, names_from = sink, names_prefix = "Sink", values_from = unique)

Вывод

# A tibble: 8 x 9
# Groups:   source [8]
  source Sink1 Sink2 Sink3 Sink4 Sink5 Sink6 Sink7 Sink8
   <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1      1     1     0     0     1     0     0     0     0
2      2     1     0     1     0     0     1     0     0
3      3     0     0     1     1     0     0     1     0
4      4     0     0     0     1     1     1     0     0
5      5     0     0     1     1     0     0     1     0
6      6     0     0     1     0     0     0     0     1
7      7     1     0     1     0     1     0     0     0
8      8     0     0     0     0     1     0     0     0

Редактировать :

Вот пересмотренный подход, который учитывает количество различных частиц, которые имеют одинаковые sink и source.

df %>%
  group_by(sink, source) %>%
  summarise(unique = n_distinct(particle)) %>%
  distinct() %>%
  right_join(expand.grid(source = 1:8, sink = 1:8)) %>%
  replace_na(list(unique = 0)) %>%
  pivot_wider(id_cols = source, names_from = sink, names_prefix = "Sink", values_from = unique)

Выход

# A tibble: 8 x 9
  source Sink1 Sink2 Sink3 Sink4 Sink5 Sink6 Sink7 Sink8
   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1      1     1     0     0     1     0     0     0     0
2      2     1     0     1     0     0     1     0     0
3      3     0     0     1     1     0     0     2     0
4      4     0     0     0     1     1     1     0     0
5      5     0     0     1     1     0     0     1     0
6      6     0     0     1     0     0     0     0     1
7      7     1     0     1     0     1     0     0     0
8      8     0     0     0     0     1     0     0     0

Редактировать :

С исправленными данными и базой R, вы также можете рассмотреть следующее:

df$source = factor(df$source, levels = 1:8)
df$sink = factor(df$sink, levels = 1:8)

df2 <- aggregate(particle ~ source + sink, df, function(x) length(unique(x)))

xtabs(particle ~ source + sink, data = df2)

Данные

df <- data.frame(
  particle = c(1:7, 1:7, 1:9),
  source = c(1:7,1:7,1:8,3),
  sink = c(1,1,4,6,7,8,5,4,6,7,5,4,8,3,1,3,3,4,3,3,1,5,7)
)
...