R比较所有列对的每个值

时间:2013-03-12 21:21:19

标签: r

我有一个18x18的数据框,我希望将所有可能的columsn对彼此进行比较,这样对于每对两列,将18行中的值相互比较。

由于我的数据太大而无法放在这里,我写了一个小例子,说明我到目前为止所得到的:

> a <- c(1:18)
> b <- c(18:1)
> c <- c(1:9,18:10)
data <- as.data.frame(matrix(c(a,b,c), ncol = 3, nrow = 18))
> data
   V1 V2 V3
1   1 18  1
2   2 17  2
3   3 16  3
4   4 15  4
5   5 14  5
6   6 13  6
7   7 12  7
8   8 11  8
9   9 10  9
10 10  9 18
11 11  8 17
12 12  7 16
13 13  6 15
14 14  5 14
15 15  4 13
16 16  3 12
17 17  2 11
18 18  1 10

说,我想比较col V1和V3,两列(V1和V3)中的相等值都分配0,当第一个col(V1)的值更大时,分配1,当第二列(V3)的值越大,分配为2。 我可以使用以下代码手动为每一对执行此操作,将结果转换为新的数据帧freqcomp:

> freqcomp <- as.data.frame(table(ifelse(data[,1]==data[,3],0,ifelse(data[,1]>data[,3],1,ifelse(data[,1]<data[,3],2,NA)))))
> 
> freqcomp
  Var1 Freq
1    0   10
2    1    4
3    2    4

我如何自动化所有列的比较?是否有一个很好的for循环来运行所有列或我可以使用的任何其他函数?

1 个答案:

答案 0 :(得分:3)

您需要使用combn()apply()

apply(combn(1:length(data), 2), 2, function(x) {
    as.data.frame(table(
        factor(sign(data[,x[1]] - data[,x[2]]), levels=c(0,1,-1), labels=c(0,1,2))
    ))
})

(为了便于阅读,分为多行。)

它给了我:

[[1]]
  Var1 Freq
1    0    0
2    1    9
3    2    9

[[2]]
  Var1 Freq
1    0   10
2    1    4
3    2    4

[[3]]
  Var1 Freq
1    0    0
2    1    9
3    2    9

编辑:为每个data.frame命名列很简单:

apply(combn(1:length(data), 2), 2, function(x) {
    result <- as.data.frame(table(
        factor(sign(data[,x[1]] - data[,x[2]]), levels=c(0,1,-1), labels=c(0,1,2))
    ))
    colnames(result)[1] <- paste(x, collapse="|")
    return(result)
})