我有一个41x41的相似性矩阵(或数据框),就像下面一样(我在附件中附上完整版本):
V1 V2 V3 V4 V5 V6
V1 1 0.068 0.211 0.285 0.198 0.047
V2 0.068 1 0.851 0.450 0.277 0.014
V3 0.211 0.851 1 0.660 0.420 0.113
V4 0.285 0.450 0.660 1 0.896 0.466
V5 0.198 0.277 0.420 0.896 1 0.241
V6 0.047 0.014 0.113 0.466 0.241 1
我想为每个向量(Vx)建立一个推荐列表,第一个地方最相似,最后一个不同。所以我认为我需要提取两列(或两行),通过减少对值进行排序,并提取列名称。 但是,当我尝试自动选择列时,它不起作用。
ms<-readLines("E:/exp/ccsm.txt", encoding = "UTF-8")
d = as.data.frame(ms)
for(dcol in 2:length(ms))
{
temp<-d[,c(1,dcol)]
nlist<-temp[order(d[,dcol], decreasing=T)]
lname<-nlist[,1]
}
Show Traceback
Rerun with Debug
Error in `[.data.frame`(d, , c(1, dcol)) : undefined columns selected
似乎变量不能是列/行号?但是可能需要更大的相似性矩阵才能进行处理。如果它无法通过某种循环实现,那将是一场灾难。 我想知道你是否可以就解决这个问题给我一些建议。如果您能尽快回复,我将不胜感激。期待收到你的回复。
答案 0 :(得分:1)
在我看来,您的主要问题是您没有正确地将文件读入数据框。
我将您的示例数据保存到我的R会话的pwd中的ccsm.txt
,然后执行以下操作:
ms <- readLines('ccsm.txt',encoding='UTF-8');
ms;
## [1] " V1 V2 V3 V4 V5 V6"
## [2] " V1 1 0.068 0.211 0.285 0.198 0.047"
## [3] " V2 0.068 1 0.851 0.450 0.277 0.014"
## [4] " V3 0.211 0.851 1 0.660 0.420 0.113"
## [5] " V4 0.285 0.450 0.660 1 0.896 0.466"
## [6] " V5 0.198 0.277 0.420 0.896 1 0.241"
## [7] " V6 0.047 0.014 0.113 0.466 0.241 1"
d <- as.data.frame(ms);
d;
## ms
## 1 V1 V2 V3 V4 V5 V6
## 2 V1 1 0.068 0.211 0.285 0.198 0.047
## 3 V2 0.068 1 0.851 0.450 0.277 0.014
## 4 V3 0.211 0.851 1 0.660 0.420 0.113
## 5 V4 0.285 0.450 0.660 1 0.896 0.466
## 6 V5 0.198 0.277 0.420 0.896 1 0.241
## 7 V6 0.047 0.014 0.113 0.466 0.241 1
names(d);
## [1] "ms"
dim(d);
## [1] 7 1
sapply(d,class);
## ms
## "factor"
正如您所看到的,您的readLines()
/ as.data.frame()
次调用产生了一个7 x 1的data.frame,其中一列包含文件原始文本行的因子。
相反,您需要使用read.table()
(还有其他选项,例如来自fread()
的data.table):
d <- read.table('ccsm.txt');
d;
## V1 V2 V3 V4 V5 V6
## V1 1.000 0.068 0.211 0.285 0.198 0.047
## V2 0.068 1.000 0.851 0.450 0.277 0.014
## V3 0.211 0.851 1.000 0.660 0.420 0.113
## V4 0.285 0.450 0.660 1.000 0.896 0.466
## V5 0.198 0.277 0.420 0.896 1.000 0.241
## V6 0.047 0.014 0.113 0.466 0.241 1.000
names(d);
## [1] "V1" "V2" "V3" "V4" "V5" "V6"
dim(d);
## [1] 6 6
sapply(d,class);
## V1 V2 V3 V4 V5 V6
## "numeric" "numeric" "numeric" "numeric" "numeric" "numeric"
不幸的是,您的代码仍然不起作用:
for (dcol in 2:length(ms)) {
temp <- d[,c(1,dcol)];
nlist <- temp[order(d[,dcol],decreasing=T)];
lname <- nlist[,1];
};
## Error in `[.data.frame`(temp, order(d[, dcol], decreasing = T)) :
## undefined columns selected
这里有两个问题。首先,ms
包含文件的原始行文本,编号为7,因为包含了标题行。但是文件中只有6行。因此d[,c(1,dcol)]
在dcol
达到7时失败。
但是dcol
永远不会达到7,因为在第一次迭代中temp[order(d[,dcol],decreasing=T)]
失败了。这是因为temp
是一个data.frame,因为它是从d
的两列切片中分配的。但是您使用单个参数对temp
进行索引,该参数为基础列表编制索引,该列表只有两个组件。 order()
调用的返回值由整数1到6组成,因为它在d
列上运行(d
中有6行),因此整数3到6对temp
data.frame。
这是我如何计算所需的输出:
apply(d,1,order,decreasing=T);
## V1 V2 V3 V4 V5 V6
## [1,] 1 2 3 4 5 6
## [2,] 4 3 2 5 4 4
## [3,] 3 4 4 3 3 5
## [4,] 5 5 5 6 2 3
## [5,] 2 1 1 2 6 1
## [6,] 6 6 6 1 1 2
如果您想要推荐的矢量而不是索引的名称,您可以这样做:
apply(d,1,function(x) names(d)[order(x,decreasing=T)]);
## V1 V2 V3 V4 V5 V6
## [1,] "V1" "V2" "V3" "V4" "V5" "V6"
## [2,] "V4" "V3" "V2" "V5" "V4" "V4"
## [3,] "V3" "V4" "V4" "V3" "V3" "V5"
## [4,] "V5" "V5" "V5" "V6" "V2" "V3"
## [5,] "V2" "V1" "V1" "V2" "V6" "V1"
## [6,] "V6" "V6" "V6" "V1" "V1" "V2"
如果你不喜欢第一排,因为它必然会排在&#34; self&#34;矢量最高,您可以使用...[-1,]
将其编入索引。