【问题标题】:R Comparing each value of all pairs of columns [duplicate]R比较所有列对的每个值[重复]
【发布时间】:2013-02-28 14:59:21
【问题描述】:

我有一个 18x18 的数据框,我想比较所有可能的列对,以便对于每对两列,将 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 并且当第二个 col (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 循环来运行所有列或我可以使用的任何其他函数?

【问题讨论】:

    标签: r


    【解决方案1】:

    你需要使用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)
    })
    

    【讨论】:

    • 非常感谢!这就像一个魅力。如何将 Var1 列名更改为正在比较的两列的组合?还是那个的子串?甚至只是数据框中的列数?
    猜你喜欢
    • 1970-01-01
    • 2020-11-03
    • 2013-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-29
    相关资源
    最近更新 更多