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

У меня есть оригинальный фрейм данных, который содержит уникальное значение в первом столбце, за которым следуют X (без минимального или максимального) строк, которые содержат значения, относящиеся к уникальному значению в первом столбце. Я ищу, чтобы найти количество уникальных пар значений из столбцов 2-инф. для каждого ряда. Данные выглядят как кадр данных ниже, но в большем масштабе. Например, «w» и «x» появлялись в одной строке 4 раза (строки 1, 3, 5, 7), «y» и «z» появлялись вместе в одной строке дважды (1, 6). Я хотел бы посчитать количество уникальных пар для всех строк.

      x$`Order ID` 1    2    3    4    5
    1            1 w    x    y    z <NA>
    2            2 x    y <NA> <NA> <NA>
    3            3 u    v    w    x    y
    4            4 w <NA> <NA> <NA> <NA>
    5            5 w    x    y <NA> <NA>
    6            6 y    z <NA> <NA> <NA>
    7            7 t    u    v    w    x

Я попытался начать с использования setDT () из библиотеки data.table для подсчета количества уникальных строк в целом, а затем разбить его на пары уникальных значений в строках, но получите ошибку, что длины строк не равны (потому что они не равны). Я не очень хорошо разбираюсь в R, но мне интересно, какую функцию можно использовать для этого. Спасибо.

РЕДАКТИРОВАТЬ: Я также попробовал функцию count () из библиотеки plyr. Он находится на правильном пути, но учитывает только все уникальные строки, а не отдельные уникальные пары в строках.

    library(plyr)
    count(transposed[, -1])

      X1   X2   X3   X4   X5 freq
    1  t    u    v    w    x    1
    2  u    v    w    x    y    1
    3  w    x    y    z <NA>    1
    4  w    x    y <NA> <NA>    1
    5  w <NA> <NA> <NA> <NA>    1
    6  x    y <NA> <NA> <NA>    1
    7  y    z <NA> <NA> <NA>    1

РЕДАКТИРОВАТЬ 2:

Желаемый вывод из этого подмножества данных:

       Pair Frequency
    1    tu         1
    2    tv         1
    3    tw         1
    4    tx         1
    5    uv         2
    6    uw         2
    7    ux         2
    8    uy         1
    9    vw         2
    10   vx         2
    11   vy         1
    12   wx         4
    13   wy         3
    14   wz         1
    15   xy         4
    16   xz         1
    17   yz         2

Подсчет количества различных комбинаций из 2 пар в каждой строке, а затем подсчет количества раз, когда эти комбинации появляются во всем наборе данных. Порядок не имеет значения (xy = yx).

Ответы [ 2 ]

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

Попробуйте это,

combs <- t(combn(sort(na.omit(unique(unlist(dat[,-1])))), 2))
head(combs, n=7)
#      [,1] [,2]
# [1,] "t"  "u" 
# [2,] "t"  "v" 
# [3,] "t"  "w" 
# [4,] "t"  "x" 
# [5,] "t"  "y" 
# [6,] "t"  "z" 
# [7,] "u"  "v" 
freqs <- apply(combs, 1, function(C) {
  sum(apply(dat[,-1], 1, function(a) all(C %in% a, na.rm = TRUE)))
})
combsDF <- as.data.frame(combs)
combsDF$freq <- freqs
combsDF
#    V1 V2 freq
# 1   t  u    1
# 2   t  v    1
# 3   t  w    1
# 4   t  x    1
# 5   t  y    0
# 6   t  z    0
# 7   u  v    2
# 8   u  w    2
# 9   u  x    2
# 10  u  y    1
# 11  u  z    0
# 12  v  w    2
# 13  v  x    2
# 14  v  y    1
# 15  v  z    0
# 16  w  x    4
# 17  w  y    3
# 18  w  z    1
# 19  x  y    4
# 20  x  z    1
# 21  y  z    2

Если вам нужны только строки с положительными совпадениями, то

combsDF[ combsDF$freq > 0, ]
#    V1 V2 freq
# 1   t  u    1
# 2   t  v    1
# 3   t  w    1
# 4   t  x    1
# 7   u  v    2
# 8   u  w    2
# 9   u  x    2
# 10  u  y    1
# 12  v  w    2
# 13  v  x    2
# 14  v  y    1
# 16  w  x    4
# 17  w  y    3
# 18  w  z    1
# 19  x  y    4
# 20  x  z    1
# 21  y  z    2

Это может быть легко расширено, чтобы включить больше, чем просто "2" комбинации.

0 голосов
/ 17 апреля 2020

Я думаю, что-то подобное может сработать для вас.

library(dplyr)
# Go through each row and count combo occurrences
data.df$counts <- NA
for (i in 1:nrow(data.df)){
  values <- unlist(data.df[i,-c(1, nrow(data.df))]) %>% 
    as.character() %>% 
    subset(!(. %in% "<NA>")) %>%
    unique()
  # if there are enough unique values to make at least one combo, count it:
  if(length(values) > 1) {
    values <- combn(x = values, m = 2)
    data.df$counts[i] <- sapply(
      X = 1:ncol(values), 
      FUN = function(x){paste(as.character(values[,x]), collapse = "")}
    ) %>% length
  } else {
    data.df$counts[i] <- 0
  }
}

РЕДАКТИРОВАТЬ Я вижу, что вы хотите подсчет для каждой пары вместо:

# Make data.frame of all possible unique combos
combos <- unlist(data.df[,-1]) %>% 
  as.character() %>% 
  subset(!(. %in% c("<NA>", ""))) %>%
  unique() %>%
  as.data.frame(x = combn(x = ., m = 2))
combos.df <- data.frame(
  combo = sapply(
    X = 1:ncol(combos), 
    FUN = function(x){paste(as.character(combos[,x]), collapse = "")}), 
  freq = 0)

# Go through each row and count combo occurences
for (i in 1:nrow(data.df)){
  values <- unlist(data.df[i,-c(1, nrow(data.df))]) %>% 
    as.character() %>% 
    subset(!(. %in% "<NA>")) %>%
    unique()
  # if there are enough unique values to make at least one combo, count it:
  if(length(values) > 1) {
    values <- combn(x = values, m = 2)
    values <- sapply(
      X = 1:ncol(values), 
      FUN = function(x){paste(as.character(values[,x]), collapse = "")})
    for(j in 1:nrow(combos.df)){
      if(combos.df$combo[j] %in% values){
        combos.df$freq[j] <- as.numeric(as.character(combos.df$freq[j])) + 1
      }
    }
  }
}
> combos.df
   combo freq
1     wx    4
2     wu    0
3     wy    3
4     wt    0
5     wv    0
6     wz    1
7     xu    0
8     xy    4
9     xt    0
10    xv    0
11    xz    1
12    uy    1
13    ut    0
14    uv    2
15    uz    0
16    yt    0
17    yv    0
18    yz    2
19    tv    1
20    tz    0
21    vz    0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...