簡體   English   中英

如何計算R中列之間的特定差異

[英]How to count specific differences between columns in R

我有一個數據框,我要遍歷每一列,並計算出其行值與其他列的行值之間存在+1(而不是-1!)之差的次數。 例如,在第2列中,有4個行值比第1列,第3列,第5列和第6列等值大1。

df <- read.table(header=T, text="
 v1  v2  v3  
  1   2   3   
  2   1   3  
  1   2   3   
  1   3   2   
  2   3   1   
  1   2   3  
 ")

看來apply函數在這里會很有用,但我對如何使用它有些困惑。

預期的輸出將類似於發生這種情況的計數矩陣。

   V1 V2 V3
V1 -  4  2
V2 4  -  3
V3 2  3  -

這也可以:

df <- read.table(header=T, text="
 v1  v2  v3  
 1   2   3   
 2   1   3  
 1   2   3   
 1   3   2   
 2   3   1   
 1   2   3")

ncols  <- ncol(df)
result <- matrix(nrow=ncols, ncol=ncols, 
                 dimnames = list(names(df),names(df)))

sapply(1:ncols, function(x) {
  result[(1:ncols)[-x],x] <<- colSums(df[,x]-df[,-x] == 1)
})

# Depending on whether you want a symmetric matrix or not:
result[lower.tri(result)] <- result[upper.tri(result)]

這給您:

   v1 v2 v3
v1 NA  4  2
v2  4 NA  3
v3  2  3 NA
sapply(colnames(df),function(v1){
      return(sapply(colnames(df),
                    function(v2){
                        return(sum(df[,v1]-df[,v2] == 1))
                    }))
  })

   v1 v2 v3
v1  0  4  2
v2  1  0  3
v3  1  1  0

如果要對稱值,請在sum使用abs(df[,v1]-df[,v2] == 1)

結果為列表(無硬編碼名稱,任意數量的列等):

library(data.table)

df <- read.table(header=T, text="
 v1  v2  v3  
                 1   2   3   
                 2   1   3  
                 1   2   3   
                 1   3   2   
                 2   3   1   
                 1   2   3  
                 ")

dt <- data.table(df)

col_comb <- combn(names(dt), 2, simplify = FALSE)
names(col_comb) <- sapply(col_comb, paste0, collapse = "-")

res <- invisible(lapply(col_comb, function(comb) {
  return(dt[, sum(get(comb[2]) - get(comb[1]) == 1)])
}))

結果:

$`v1-v2`
[1] 4

$`v1-v3`
[1] 2

$`v2-v3`
[1] 3

4列示例:

df <- read.table(header=T, text="
 v1  v2  v3  v4  
                 1   2   3   1
                 2   1   3   2
                 1   2   3   3
                 1   3   2   1
                 2   3   1   1
                 1   2   3   1
                 ")

# rest of code here

結果:

$`v1-v2`
[1] 4

$`v1-v3`
[1] 2

$`v1-v4`
[1] 0

$`v2-v3`
[1] 3

$`v2-v4`
[1] 2

$`v3-v4`
[1] 0

您可以執行以下操作。 這個想法是循環(使用sapply )遍歷各列並計算差異並輸出精確為1的差異數。相同的列比較會產生一個NA

# function
foo <- function(i,y){
  a <- c(1:3) # number of data.frame columns
  a1 <- sapply(a, function(j,ii) if(a[j] == a[ii]) NA else sum((y[,ii] - y[,j]) == 1) ,i)
  a2 <- sapply(a, function(j,ii) if(a[j] == a[ii]) NA else sum((y[,j]  - y[,ii]) == 1) ,i)
  a1+a2-1
    }

sapply(1:ncol(df), foo, df)  
      [,1] [,2] [,3]
[1,]   NA    4    2
[2,]    4   NA    3
[3,]    2    3   NA

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM