繁体   English   中英

计算 R dataframe 中的唯一行组合

[英]count unique row combinations in R dataframe

我有一个原始 dataframe 在第一列中包含一个唯一值,后面有 X(没有最小值或最大值)行,其中包含与第一列中唯一值有关的值。 我正在寻找第 2-inf 列中唯一值对的数量。 对于每一行。 数据看起来像下面的 dataframe 但规模更大。 例如,“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

我试图首先使用 data.table 库中的 setDT() 来计算一般唯一行的数量,然后将其分解为行内的唯一值对,但得到一个错误,即行的长度是不相等(因为它们不相等)。 我不精通 R 但想知道 function 可以用来做什么。 谢谢你。

编辑:我还尝试了 plyr 库中的 count() function。 这是在正确的轨道上,但只计算整个唯一行,而不是行中的单个唯一对。

    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:

来自该数据子集的所需 output:

       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)。

尝试这个,

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”组合。

我认为这样的事情可能对你有用。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM