【问题标题】:Find similar groups of numbers across rows R在行 R 中查找相似的数字组
【发布时间】:2018-02-07 13:30:38
【问题描述】:

我正在尝试在数据框中找到类似的数字模式。我有一个包含 5 列的数据框,有些列的随机数介于 3 到 50 之间。但是,对于某些行,2 或 3 列没有数字。

A   B    C   D   E
5   23   6 
9   33   7   8   12
33   7   14  
6   18   23  48 
8   44   33  7  9 

我想知道循环次数是多少,所以我很感兴趣:

  • 编号为 23 和 6 的第 1 行和第 4 行,
  • 编号为 9、33 和 8 的第 2 行和第 5 行,
  • 编号为 33 和 7 的第 2、3 和 5 行。

基本上我是在尝试获取不同组合的数量。

我对如何做到这一点有点困惑。我已尝试将数字加入列表中。

for (i in 1:dim(knots_all)[1]) {
    knots_all$list_knots <- list(sort(knots_all[i,1:5]))
}

我也尝试过intersect,但它似乎效率不高,因为 R 还考虑了我想忽略的 NA。

我想听听一些关于实现这一目标的最佳方法的想法。我一直在考虑这个问题,但我无法理解如何得到答案。我的心被卡住了,所以任何想法都非常感谢!

谢谢!

【问题讨论】:

    标签: r algorithm combinations


    【解决方案1】:

    没有您想捕捉的特定/目标模式。您似乎需要一个过程来识别数据集中出现频率更高的数字,然后查看它们出现在哪些行中。

    我将修改您的示例数据集,让数字 23 在同一行中出现两次,以说明一些有用的计数差异。

    df = read.table(text = "
    A   B    C   D   E
    5   23   6   23  NA
    9   33   7   8   12
    33   7   14  NA  NA
    6   18   23  48  NA
    8   44   33  7  9 
    ", header=T)
    
    library(dplyr)
    library(tidyr)
    
    
    df %>%
      mutate(row_id = row_number()) %>%          # add a row flag
      gather(col_name,value,-row_id) %>%         # reshape
      filter(!is.na(value)) %>%                  # exclude NAs
      group_by(value) %>%                        # for each number value
      summarise(NumOccurences = n(),                             # count occurences
                rows = paste(sort(row_id), collapse = "_"),      # capture rows
                NumRowOccurences = n_distinct(row_id),           # count occurences in unique rows
                unique_rows = paste(sort(unique(row_id)), collapse = "_")) %>%  # capture unique rows
      arrange(desc(NumOccurences))                               # order by number popularity (occurences)
    
    # # A tibble: 12 x 5
    #    value NumOccurences rows  NumRowOccurences unique_rows
    #    <int>         <int> <chr>            <int> <chr>      
    # 1     7             3 2_3_5                3 2_3_5      
    # 2    23             3 1_1_4                2 1_4        
    # 3    33             3 2_3_5                3 2_3_5      
    # 4     6             2 1_4                  2 1_4        
    # 5     8             2 2_5                  2 2_5        
    # 6     9             2 2_5                  2 2_5        
    # 7     5             1 1                    1 1          
    # 8    12             1 2                    1 2          
    # 9    14             1 3                    1 3          
    # 10   18             1 4                    1 4          
    # 11   44             1 5                    1 5          
    # 12   48             1 4                    1 4   
    

    【讨论】:

    • 谢谢!这是一个非常好的和简单的方法!我什至没有想过将数据帧转换为长格式,但这是个好主意。它避免了使用 forloops。
    • 谢谢!这是一个很好的观点!我已经处理好了,因为我想要每行不同的数字。您的答案似乎正是我正在寻找的(但不知道)。
    • 我已经更新了我的答案来解决这个问题。此外,您可以使用 NumOccurences - NumRowOccurences 差异来调查哪些数字往往会在同一行中出现多次。
    • 但是对于 300 行,变量 rows 有点难以使用。例如,数字 13 出现了 35 次,我不确定 13 是与相同的数字还是不同的数字组合出现。我可能仍需要遍历 rows 变量以了解所有组合。
    • 您可以使用列rows 作为变量,您可以计算并查看有多少个唯一数字具有此组合。如果您在可视化此变量(大字符串)时遇到问题,您可以将数据保存为 .csv 文件并进行调查。
    【解决方案2】:

    制作列表列表:

    List = [1[],2[],...,n[]].
    

    循环遍历您的数据框,并将您的示例广告 A 设为 List = [1[],2[],.5[A]..,[n]](索引 = 5)。每列依此类推。

    在遍历列表后,检查列表(在列表中)是否已填满并且有多个列。

    这应该可以帮助您入门。 祝你好运

    【讨论】:

      【解决方案3】:

      这是一种可以检测出现在两列中的数字的算法。

      df <- data.frame(A = c(5, 23, 6, NA, NA),
                B = c(9, 33, 7, 8, 12),
                C = c(33, 7, 14, NA, NA),
                D = c(6, 18, 23, 48, NA),
                E = c(8, 44, 33, 7, 9))
      
      L <- as.list(df)
      
      
      LL <- rep(list(rep(list(NA), length(L))), length(L))
      
      for(i in 1:length(L)){
        for(j in 1:length(L))
          LL[[i]][[j]] <- intersect(L[[i]], L[[j]])
      }
      

      要查看第 1 列和第 4 列中的重叠数字:

      LL[[1]][[4]]
      [1] 23  6 NA
      

      要查看所有重叠的数字:

      unique(unlist(LL))
      [1]  5 23  6 NA  9 33  7  8 12 14 18 48 44
      

      可以稍微改变一下(通过在嵌套循环中添加一个级别以及 for 循环)以查看 3 个不同列中的 pesence 等

      【讨论】:

      • 谢谢!使用我尝试做的intersect 是个好主意。我想到了类似的东西,但它似乎不是最有效的方法,因为我的原始数据框有 300 行(忘了提)。
      【解决方案4】:

      处理NA 的一个例子是临时用随机生成的数字填充它们:

      # data
      df <- data.frame(A = c(5,9,33,6,8),
                       B = c(23,33,7,18,44),
                       C = c(6,7,14,23,33),
                       D = c(NA, 8, NA, 48, 7),
                       E = c(NA, 12, NA, NA, 9))
      
      # fill NA with random numbers
      set.seed(1)
      df2 <- as.data.frame(do.call(cbind, lapply(df, function(x) ifelse(is.na(x), rnorm(1), x))))
      
      > df2
         A  B  C          D          E
      1  5 23  6 -0.6264538  0.1836433
      2  9 33  7  8.0000000 12.0000000
      3 33  7 14 -0.6264538  0.1836433
      4  6 18 23 48.0000000  0.1836433
      5  8 44 33  7.0000000  9.0000000
      
      
      # split data by rows
      df2 <- split(df2, seq_along(df2))
      
      # compare rows with each other
      temp <- lapply(lapply(df2, function(x) lapply(df2, function(y) x %in% y)), function(x) do.call(rbind, x))
      
      # delete self comparisons
      output <- lapply(1:5, function(x) temp[[x]] <- temp[[x]][-x,])
      

      结果:

      [[1]]
         [,1]  [,2]  [,3]  [,4]  [,5]
      2 FALSE FALSE FALSE FALSE FALSE
      3 FALSE FALSE FALSE  TRUE  TRUE
      4 FALSE  TRUE  TRUE FALSE  TRUE
      5 FALSE FALSE FALSE FALSE FALSE
      
      [[2]]
         [,1]  [,2]  [,3]  [,4]  [,5]
      1 FALSE FALSE FALSE FALSE FALSE
      3 FALSE  TRUE  TRUE FALSE FALSE
      4 FALSE FALSE FALSE FALSE FALSE
      5  TRUE  TRUE  TRUE  TRUE FALSE
      
      [[3]]
         [,1]  [,2]  [,3]  [,4]  [,5]
      1 FALSE FALSE FALSE  TRUE  TRUE
      2  TRUE  TRUE FALSE FALSE FALSE
      4 FALSE FALSE FALSE FALSE  TRUE
      5  TRUE  TRUE FALSE FALSE FALSE
      
      [[4]]
         [,1]  [,2]  [,3]  [,4]  [,5]
      1  TRUE FALSE  TRUE FALSE  TRUE
      2 FALSE FALSE FALSE FALSE FALSE
      3 FALSE FALSE FALSE FALSE  TRUE
      5 FALSE FALSE FALSE FALSE FALSE
      
      [[5]]
         [,1]  [,2]  [,3]  [,4]  [,5]
      1 FALSE FALSE FALSE FALSE FALSE
      2  TRUE FALSE  TRUE  TRUE  TRUE
      3 FALSE FALSE  TRUE  TRUE FALSE
      4 FALSE FALSE FALSE FALSE FALSE
      

      【讨论】:

        猜你喜欢
        • 2022-12-10
        • 1970-01-01
        • 2022-10-16
        • 2015-04-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多