我想按行进行分层聚类,然后按列进行。我想出了解决方案的全部内容:
#! /path/to/my/Rscript --vanilla
args <- commandArgs(TRUE)
mtxf.in <- args[1]
clusterMethod <- args[2]
mtxf.out <- args[3]
mtx <- read.table(mtxf.in, as.is=T, header=T, stringsAsFactors=T)
mtx.hc <- hclust(dist(mtx), method=clusterMethod)
mtx.clustered <- as.data.frame(mtx[mtx.hc$order,])
mtx.c.colnames <- colnames(mtx.clustered)
rownames(mtx.clustered) <- mtx.clustered$topLeftColumnHeaderName
mtx.clustered$topLeftColumnHeaderName <- NULL
mtx.c.t <- as.data.frame(t(mtx.clustered), row.names=names(mtx))
mtx.c.t.hc <- hclust(dist(mtx.c.t), method=clusterMethod)
mtx.c.t.c <- as.data.frame(mtx.c.t[mtx.c.t.hc$order,])
mtx.c.t.c.t <- as.data.frame(t(mtx.c.t.c))
mtx.c.t.c.t.colnames <- as.vector(names(mtx.c.t.c.t))
names(mtx.c.t.c.t) <- mtx.c.colnames[as.numeric(mtx.c.t.c.t.colnames) + 1]
write.table(mtx.c.t.c.t, file=mtxf.out, sep='\t', quote=F, row.names=T)
变量mtxf.in
和mtxf.out
分别代表输入矩阵和聚类输出矩阵文件。变量clusterMethod
是hclust
方法之一,例如single
,average
等。
作为示例输入,这是一个数据矩阵:
topLeftColumnHeaderName col1 col2 col3 col4 col5 col6
row1 0 3 0 0 0 3
row2 6 6 6 6 6 6
row3 0 3 0 0 0 3
row4 6 6 6 6 6 6
row5 0 3 0 0 0 3
row6 0 3 0 0 0 3
运行此脚本,我从mtxf.in
丢失了左上角元素。以下是此脚本的输出:
col5 col4 col1 col3 col2 col6
row6 0 0 0 0 3 3
row5 0 0 0 0 3 3
row1 0 0 0 0 3 3
row3 0 0 0 0 3 3
row2 6 6 6 6 6 6
row4 6 6 6 6 6 6
我的问题:除了寻找保留输入矩阵文件原始结构的方法之外,我还不知道它消耗了多少内存,或者是否有更快更干净,更“R”的方式这样做。
真的难以通过R中的行和列进行聚类吗?有没有建设性的方法来改进这个脚本?谢谢你的建议。
答案 0 :(得分:4)
一旦您清理了数据(即删除了第一列),这实际上只需要三行代码:
清理数据(从第一列分配行名,然后删除第一列):
dat <- mtfx.in
rownames(dat) <- dat[, 1]
dat <- dat[, -1]
群集和重新排序:
row.order <- hclust(dist(dat))$order
col.order <- hclust(dist(t(dat)))$order
dat[row.order, col.order]
结果:
col5 col4 col1 col3 col2 col6
row6 0 0 0 0 3 3
row5 0 0 0 0 3 3
row1 0 0 0 0 3 3
row3 0 0 0 0 3 3
row2 6 6 6 6 6 6
row4 6 6 6 6 6 6
答案 1 :(得分:0)
我会说实话,我并不完全清楚你为什么要做你正在做的事情,所以我完全有可能误解了你在寻找什么。如果我离开基地,请告诉我,我会删除这个答案。
但我怀疑,如果您使用row.names = 1
读取数据以指示第一列实际是行名,那么您的生活会更容易(并且您的结果实际上是正确的)。例如:
#Read the data in
d1 <- read.table(textConnection("topLeftColumnHeaderName col1 col2 col3 col4 col5 col6
row1 0 3 0 0 0 3
row2 6 6 6 6 6 6
row3 0 3 0 0 0 3
row4 6 6 6 6 6 6
row5 0 3 0 0 0 3
row6 0 3 0 0 0 3"),
sep = "",as.is = TRUE,header = TRUE,
stringsAsFactors = TRUE,row.names = 1)
#So d1 looks like this:
d1
col1 col2 col3 col4 col5 col6
row1 0 3 0 0 0 3
row2 6 6 6 6 6 6
row3 0 3 0 0 0 3
row4 6 6 6 6 6 6
row5 0 3 0 0 0 3
row6 0 3 0 0 0 3
#Simple clustering based on rows
clus1 <- hclust(dist(d1))
d2 <- d1[clus1$order,]
d2
col1 col2 col3 col4 col5 col6
row6 0 3 0 0 0 3
row5 0 3 0 0 0 3
row1 0 3 0 0 0 3
row3 0 3 0 0 0 3
row2 6 6 6 6 6 6
row4 6 6 6 6 6 6
#Now cluster on columns and display the result
clus2 <- hclust(dist(t(d2)))
t(t(d2)[clus2$order,])
col5 col4 col1 col3 col2 col6
row6 0 0 0 0 3 3
row5 0 0 0 0 3 3
row1 0 0 0 0 3 3
row3 0 0 0 0 3 3
row2 6 6 6 6 6 6
row4 6 6 6 6 6 6
因为你标记了这个code-review
我想我也会在风格上指出,许多R人不喜欢使用T
和F
来表示布尔,因为他们可以被屏蔽,而TRUE
和FALSE
不能。