简体   繁体   English

R:在 for 循环中命名矩阵行/列在控制台中有效,但在编织时无效

[英]R: Naming matrix rows/columns in a for-loop works in console, but not when knitting

I am attempting to use a for loop to rename the rows and columns of a matrix via the following code:我正在尝试使用for循环通过以下代码重命名矩阵的行和列:

Z = matrix(c(1:120), 15, 8)
for (i in 1:15) {
  rownames(Z)[i] = paste0("[", format((-1)*(4-(i/10)), nsmall=1), "]")
}
for (j in 1:8) {
  colnames(Z)[j] = paste0("[", (j-1)/100, "]")
}

This works as expected when entered into the console, and produces the following matrix Z :这在进入控制台时按预期工作,并产生以下矩阵Z

       [.00] [.01] [.02] [.03] [.04] [.05] [.06] [.07]
[-3.9]     1    16    31    46    61    76    91   106
[-3.8]     2    17    32    47    62    77    92   107
[-3.7]     3    18    33    48    63    78    93   108
[-3.6]     4    19    34    49    64    79    94   109
[-3.5]     5    20    35    50    65    80    95   110
[-3.4]     6    21    36    51    66    81    96   111
[-3.3]     7    22    37    52    67    82    97   112
[-3.2]     8    23    38    53    68    83    98   113
[-3.1]     9    24    39    54    69    84    99   114
[-3.0]    10    25    40    55    70    85   100   115
[-2.9]    11    26    41    56    71    86   101   116
[-2.8]    12    27    42    57    72    87   102   117
[-2.7]    13    28    43    58    73    88   103   118
[-2.6]    14    29    44    59    74    89   104   119
[-2.5]    15    30    45    60    75    90   105   120

However, I need to include this in an R Markdown document that knits to PDF, as in this MWE:但是,我需要将其包含在编织为 PDF 的 R Markdown 文档中,如在此 MWE 中所示:

---
title: "Title"
author: "Author"
date: "1970-01-01"
output: pdf_document
---

```{r}
Z = matrix(c(1:120), 15, 8)
for (i in 1:15) {
  rownames(Z)[i] = paste0("[", format((-1)*(4-(i/10)), nsmall=1), "]")
}
for (j in 1:8) {
  colnames(Z)[j] = paste0("[", (j-1)/100, "]")
}
```

When trying to knit this document, R Markdown returns the error尝试编织此文档时,R Markdown 返回错误

Error in dimnames(x) <- dn : length of 'dimnames' [1] not equal to array extent

and the execution halts.并且执行停止。

I found that the above error has been extensively discussed, but that the cause of the error is when attempting to supply too few or too many names for the number of rows or columns.我发现上述错误已被广泛讨论,但错误的原因是尝试为行数或列数提供太少或太多的名称。 However, that should not be the case here, and since the code does not return this error when entered into the console, I have been unable to find a cause for Markdown rejecting it.但是,这里不应该是这种情况,并且由于代码在进入控制台时不会返回此错误,因此我一直无法找到 Markdown 拒绝它的原因。

(I realize that assigning vectors to the row and column names is preferred, especially since the names are known; but this is for a university class assignment which is intended to familiarize me with loops, and so the assignment requires that everything must be done inside loops.) (我意识到将向量分配给行和列名称是首选,特别是因为名称是已知的;但这是为了让我熟悉循环的大学课堂作业,因此作业要求所有内容都必须在内部完成循环。)

I am using R version 3.6.2 and RStudio version 1.2.5033 on Windows 10 version 1909 build 18363.1082.我在 Windows 10 版本 1909 版本 18363.1082 上使用 R 版本 3.6.2 和 RStudio 版本 1.2.5033。 Any help is appreciated!任何帮助表示赞赏!

Edit 1: Output of sessionInfo() as requested by @Wil:编辑 1:@Wil 要求的sessionInfo()输出:

R version 3.6.2 (2019-12-12)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 18363)

Matrix products: default

Random number generation:
 RNG:     Mersenne-Twister 
 Normal:  Inversion 
 Sample:  Rounding 
 
locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
 [1] compiler_3.6.2  htmltools_0.4.0 tools_3.6.2     yaml_2.2.0      Rcpp_1.0.3     
 [6] rmarkdown_2.0   knitr_1.26      digest_0.6.23   xfun_0.12       rlang_0.4.4    
[11] evaluate_0.14  

For a matrix Z without any defined row or column names, the value of rownames(Z) and colnames(Z) is NULL .对于一个矩阵Z而没有任何限定的行或列的名称,值rownames(Z)colnames(Z)NULL You're getting this error because you're trying to subset [i] into NULL , which doesn't work.您收到此错误是因为您试图将[i]子集化为NULL ,但这是行不通的。

Z = matrix(c(1:120), 15, 8)
rownames(Z) # NULL
rownames(Z)[1] # NULL 
rownames(Z)[1] <- "foo" 
# Error in dimnames(x) <- dn : length of 'dimnames' [1] not equal to array extent

Note that this is discussed in the base R documentation for colnames() / rownames() :注意,这是基R文件中所讨论的colnames() / rownames()

constructions such as建筑如

rownames(x)[3] <- "c"

may not work unless x already has dimnames, since this will create a length-3 value from the NULL value of rownames(x).除非 x 已经有dimnames,否则可能不起作用,因为这将从rownames(x) 的NULL 值创建一个长度为3 的值。

You can assign rownames with a vectorized input, such as:可以使用矢量化输入分配行名,例如:

rownames(Z) <- paste0("[", format((-1)*(4-(1:15/10)), nsmall=1), "]")

But from your post it sounds like this exercise is focused on for -loops.但是从您的帖子看来,这个练习的重点是for循环。 Per the docs, this isn't a viable option for setting names on a new matrix.根据文档,这不是在新矩阵上设置名称的可行选项。

If you can't use a purely vectorized approach, the closest solution involving a for -loop that I can think of is to loop the rowname values into a vector, then assign the vector as rownames(Z) .如果您不能使用纯矢量化方法,那么我能想到的涉及for循环的最接近解决方案是将 rowname 值循环到一个向量中,然后将该向量分配为rownames(Z) But this seems like a needless middle step, so I'm not sure it's really a useful pattern to learn.但这似乎是一个不必要的中间步骤,所以我不确定它是否真的是一个有用的学习模式。

new_rownames <- vector(mode = "character", length = nrow(Z))

for (i in 1:15) {
  new_rownames[i] = paste0("[", format((-1)*(4-(i/10)), nsmall=1), "]")
}

rownames(Z) <- new_rownames

Another option might be to assign an empty set of values to rownames/colnames for Z :另一种选择可能是为Z rownames/colnames 分配一组空值:

Z = matrix(c(1:120), 15, 8, dimnames = list(1:15, 1:8))

Then you could use your original loops as intended.然后您可以按预期使用您的原始循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM