在R中插入可变长度行以用于2D矩阵

时间:2015-06-19 10:33:38

标签: r matrix transpose insertion

我有以下格式的数据

Reg_No     Subject
  AA11     Physics
  AA11   Chemistry
  AA12     English
  AA12       Maths
  AA12     Physics

我正在尝试将此数据转换为行

Physics   Chemistry
English       Maths   Physics

我知道每个学生最多可以参加8个科目

我正在尝试创建一个矩阵,可以将上述数据存储为变量行(每个学生都有不同数量的主题)

我写了以下代码

# read csv file
Term4 <- read.csv("Term4.csv")
# Find number of Students
Matrix_length <- length(unique(Term4$Reg_No))
# Uniquely store their reg number
Student <- unique(Term4$Reg_No)
# create matrix to be inserted as csv
out <- matrix(NA, nrow=Matrix_length , ncol=8) # max subjects = 8 so ncol =8
# iterate to get each reg number's subjects
for (n in 1:Matrix_length) {
    y <- Term4[Term4[,"Reg_No"] == Student[n],]$Subject
    # transpose Courses as a single column into row and insert it in the matrix
    out[n,] <- t(y)
}

我收到以下错误

  

out [n,]&lt; - t(y)出错:
  要替换的项目数量不是替换长度的倍数

有人可以告诉我如何解决这个错误

谢谢和问候

1 个答案:

答案 0 :(得分:1)

reshape()可以做到这一点:

df <- data.frame(Reg_No=c('AA11','AA11','AA12','AA12','AA12'), Subject=c('Physics','Chemistry','English','Maths','Physics') );
reshape(transform(df,time=ave(c(Reg_No),Reg_No,FUN=seq_along)),dir='w',idvar='Reg_No');
##   Reg_No Subject.1 Subject.2 Subject.3
## 1   AA11   Physics Chemistry      <NA>
## 3   AA12   English     Maths   Physics

这将生成一个data.frame,其中包含覆盖所有主题所需的列数。

您的代码失败的原因是您已经使用8列预分配了矩阵,但每个分配的RHS将只包含与原始data.frame中当前学生n一样多的主题。 R拒绝索引分配,其目标长度不能被RHS长度整除(实际上对于普通向量,它只是一个警告,但对于矩阵,它似乎是一个错误;无论如何,它可能永远不是正确的事情)。 / p>

一般而言,如果您确实需要执行这种不可分割的任务,您可以通过附加NA来将RHS扩展到足够的长度。这可以通过rep()c()来完成,但实际上使用越界索引实现了一种优雅而简单的方法。这是一个演示:

m <- matrix(NA_character_,2,8);
m;
##      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
## [1,] NA   NA   NA   NA   NA   NA   NA   NA
## [2,] NA   NA   NA   NA   NA   NA   NA   NA
m[1,] <- letters[1:3]; ## fails; indivisible
## Error in m[1, ] <- letters[1:3] :
##   number of items to replace is not a multiple of replacement length
m[2,] <- letters[1:3][1:ncol(m)]; ## works
m;
##      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
## [1,] NA   NA   NA   NA   NA   NA   NA   NA
## [2,] "a"  "b"  "c"  NA   NA   NA   NA   NA