我有一个数据框,我希望遍历每一列,并计算其行值与其他列的行值之间存在+1(不是-1!)差异的次数。例如,在第2列中,有4个行值大于它们的列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 -
答案 0 :(得分:2)
这也有效:
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
答案 1 :(得分:1)
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
如果您想要对称值,请改用abs(df[,v1]-df[,v2] == 1)
中的sum
。
答案 2 :(得分:0)
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
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
答案 3 :(得分: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