从R中整个数据帧的行中查找成对的值

时间:2018-08-26 03:12:10

标签: r dataframe

我正在尝试完善我的R技能并达到极限。

我正在尝试找到以下解决方案的问题。 假设我的数据框如下所示,

n = c(2, 15, 31 , 33) 
n2 = c( 10 , 9, 10 , 40) 
n3 = c( 11 , 10 , 11 , 42) 
df = data.frame(n , n2 , n3)



> df
  n n2 n3
1  2 10 11
2 15  9 10
3 31 10 11
4 33 40 42

如果我想遍历每一行,并生成一个随机对:例如2,10,遍历其余各行,以找到重复的对,并打印出常见的对和出现次数,如何我能做到吗?

在上面的示例中,唯一重复的对是第1行和第3行的10和11。

到目前为止,我对伪代码的考虑如下

for(each row in the dataframe)
{
  for (each of the values in the row)
   { 
     for every pair
   }
  find a repeated pair
  if found store in a dataframe
}

,并使用 combn 函数查找随机对。

但是在遍历数据帧行的迭代过程中,我有些失落。 请帮助。 非常感谢!

2 个答案:

答案 0 :(得分:1)

我想这就是你想要的。不用考虑为每行选择两个的每种组合,我们将获得两个列号的每种组合-每行都相同。然后,我们使用plyr::count作为便利函数来一次为整个数据帧计数具有相同值的行。这样,我们可以遍历列索引的组合而不是遍历行。我使用apply,但您可以将其编写为for循环。

pairs = combn(ncol(df), m = 2)
result = apply(pairs, MAR = 2, FUN = function(p) {
  plyr::count(df[p])
})
names(result) = apply(pairs, MAR = 2, FUN = paste, collapse = "_")

结果是一个list,其中每个项目都是一个具有两列的数据帧和一个freq列,其中给出了每个值对出现的原始数据中的行数。

result
# $`1_2`
#    n n2 freq
# 1  2 10    1
# 2 15  9    1
# 3 31 10    1
# 4 33 40    1
# 
# $`1_3`
#    n n3 freq
# 1  2 11    1
# 2 15 10    1
# 3 31 11    1
# 4 33 42    1
# 
# $`2_3`
#   n2 n3 freq
# 1  9 10    1
# 2 10 11    2
# 3 40 42    1

如果您想省略不重复的值,我们可以将它们子集化:

lapply(result, subset, freq > 1)
# $`1_2`
# [1] n    n2   freq
# <0 rows> (or 0-length row.names)
# 
# $`1_3`
# [1] n    n3   freq
# <0 rows> (or 0-length row.names)
# 
# $`2_3`
#   n2 n3 freq
# 2 10 11    2

答案 1 :(得分:0)

方法略有不同

n = c(2, 15, 31 , 15) # changed the dataset to have some common pairs in n and n2 too
n2 = c( 10 , 9, 10 , 9) 
n3 = c( 11 , 10 , 11 , 42) 
df = data.frame(n , n2 , n3)

library(dplyr)
library(rlang)
library(utils)

cols<-colnames(df) # define the columns that you want to do the pair checking for

combinations<- as.data.frame(combn(cols,2),stringsAsFactors = FALSE)
# picks up all combinations of columns


#iterates over each pair of columns
 all_combs<- lapply(names(combinations[cols1]), function(x){
    df %>%
      group_by(!! sym( combinations[[x]][1]),!! sym( combinations[[x]][2])) %>%
      filter(n()>1) # groups by the two columns, and filters out pairs that occur more than once. You can add a distinct command below if you 
#dont want them repeated


  })
 all_combs_df <- do.call("rbind", all_combs)# all_combs is in a list format, use rbind to convert into a dataframe
 all_combs_df

输出是这个

      n    n2    n3
  <dbl> <dbl> <dbl>
1   15.    9.   10.
2   15.    9.   42.
3    2.   10.   11.
4   31.   10.   11.