我有一个 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
似乎变量不能是列/行号?但是可能有一个更大的相似矩阵需要处理。如果它不能通过某种循环实现,那将是一场灾难。
我想知道你是否可以给我一些解决这个问题的建议。如果您能在方便时尽早回复,我将不胜感激。期待您的回音。
最佳答案
在我看来,您的主要问题是您没有将文件正确读入 data.frame。
我将您的样本数据保存到 ccsm.txt
在我的 R session 的密码中,然后运行以下命令:
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()
的返回值call 由整数 1 到 6 组成,因为它对 d
的列进行操作(并且在 d
中有 6 行),因此整数 3 到 6 都超出了 temp
下的二元列表的范围数据框。这是我计算所需输出的方法:
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,]
索引它。 .
关于r - 如何在R中自动处理矩阵(数据框),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32033887/