根据数据表条目获取唯一的行名和列名对

时间:2021-03-31 00:56:47

标签: r data.table

这是我的数据表:

fgets()

我正在尝试根据条目获取唯一的行名和列名对。例如,如果我查看 A B C A 1 0.8 0.2 B 0.8 1 0.3 C 0.2 0.3 1 ,我的输出将是:

> 0.5

如果我查看 A B 0.8 ,我的输出将是:

< 0.5

4 个答案:

答案 0 :(得分:3)

这是一个经典的 melt 情况(尽管它需要使用 upper 或 lower.tri 进行一些调味)


dat <- read.table(text=
"    A    B    C
A   1   0.8  0.2
B  0.8   1   0.3
C  0.2  0.3   1
", header=TRUE )
dat[ !upper.tri(dat) ] <- NA

dat <- as.data.frame( dat )
dat <- tibble::rownames_to_column( dat, "V1" )
setDT(dat)

use.this <- melt( dat, id.vars="V1", variable.name="V2" )[ !is.na(value) ]

use.this[ value < .5 ]

use.this[ value > 0.5 ]

看起来像这样:


> use.this[ value < .5 ]
   V1 V2 value
1:  A  C   0.2
2:  B  C   0.3

> use.this[ value > .5 ]
   V1 V2 value
1:  A  B   0.8

答案 1 :(得分:0)

在基数 R 中,使用 whicharr.ind = TRUE 来获取满足条件的行号和列号。

df[lower.tri(df, diag = TRUE)] <- NA
mat <- which(df < 0.5, arr.ind = TRUE)
data.frame(rowname = rownames(df)[mat[, 1]], 
           colname = colnames(df)[mat[, 2]], 
           value = df[mat])

#  rowname colname value
#1       A       C   0.2
#2       B       C   0.3

数据

df <- structure(list(A = c(1, 0.8, 0.2), B = c(0.8, 1, 0.3), C = c(0.2, 
0.3, 1)), class = "data.frame", row.names = c("A", "B", "C"))

答案 2 :(得分:0)

这是另一种选择:

M <- matrix(c(1,0.8,0.2,0.8,1,0.3,0.2,0.3,1), nrow=3L, 
    dimnames=list(LETTERS[1:3], LETTERS[1:3]))

allDT <- data.table(rn=rep(rownames(M), nrow(M)), 
    cn=rep(colnames(M), each=ncol(M)), 
    val=as.vector(M))
DT <- unique(allDT[, .(val=val), .(rn=pmin(rn, cn), cn=pmax(rn, cn))])
DT[val<0.5]

答案 3 :(得分:0)

问题已被标记为 。因此,这是一个仅使用 语法的简单解决方案。此外,它还建议了需要较少击键的查找功能(编辑: 3 种不同风格)。

library(data.table)
wide <- fread("    A    B    C
A   1   0.8  0.2
B  0.8   1   0.3
C  0.2  0.3   1")
long <- melt(wide, id.var = "V1", variable.name = "V2", 
             variable.factor = FALSE)[V1 < V2]

long
<块引用>
   V1 V2 value
1:  A  B   0.8
2:  A  C   0.2
3:  B  C   0.3

请注意,wide 的上三角部分是在整形为长格式后通过子集 [V1 < V2] 来选取的,以确保只考虑唯一的对。

long 可以通过子集查询,例如,

long[value < 0.5]
<块引用>
   V1 V2 value
1:  A  C   0.2
2:  B  C   0.3
long[value > 0.5]
<块引用>
   V1 V2 value
1:  A  B   0.8

查找功能

long 可以通过定义一个查找函数来查询:

l <- function(cond) eval(parse(text = paste0("long[value", cond, "]")))

可以调用,例如,

l("< .5")
<块引用>
   V1 V2 value
1:  A  C   0.2
2:  B  C   0.3
l("> .5")
<块引用>
   V1 V2 value
1:  A  B   0.8
l("== .3")
<块引用>
   V1 V2 value
1:  B  C   0.3

编辑:带有 2 个参数的查找函数

或者,可以定义查找函数以允许使用 2 个参数,一个用于比较运算符,一个用于数值:

l2 <- function(op, v) long[do.call(op, list(value, v))]

l2("%between%", c(0.25, 0.95))
<块引用>
   V1 V2 value
1:  A  B   0.8
2:  B  C   0.3

或者,使用用于在 data.table 上编程的新界面(适用于 data.table 开发版本 1.14.1):

l3 <- function(op, v) long[op(value, v), env = list(op = as.name(op), v = v)]

l3("%in%", c(0.2, 0.3))
<块引用>
   V1 V2 value
1:  A  C   0.2
2:  B  C   0.3