我有一个41×41的相似性矩阵(或数据框),就像下面一样(我在附件中附上完整版本):
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
似乎变量不能是列/行号?但是可能需要更大的相似性矩阵才能进行处理.如果它无法通过某种循环实现,那将是一场灾难.
我想知道你是否可以就解决这个问题给我一些建议.如果您能尽快回复,我将不胜感激.期待您的回音.
最佳答案 在我看来,你的主要问题是你没有正确地将文件读入data.frame.
我将您的示例数据保存到我的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乘1的data.frame,其中一列包含文件中原始文本行的因子.
相反,您需要使用read.table()
(还有其他选项,例如data.table fread()
):
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行.因此当dcol达到7时d [,c(1,dcol)]将失败.
但是dcol永远不会达到7,因为在第一次迭代中,temp [order(d [,dcol],decrease = T)]失败了.这是因为temp是data.frame,因为它是从d的两列切片分配的.但是您使用单个参数索引临时值,该参数为基础列表编制索引,该列表只有两个组件. order()调用的返回值由整数1到6组成,因为它在d列上运行(d中有6行),因此整数3到6都超出了两个范围临时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"
如果你不喜欢第一行,因为它必然会将“自我”向量排在最高位置,你可以用… [ – 1,]索引它.