Here are some solutions that only use the base of R. All three solutions use this new studentno
variable:
studentno <- with(test, ave(schoolid, schoolid, FUN = seq_along))
1) tapply
with(test, tapply(score, list(schoolid, studentno), c))
giving:
1 2
1 1 10
2 20 40
3 20 NA
2) reshape
# rename score to student and append studentno column
test2 <- transform(test, student = score, score = NULL, studentno = studentno)
reshape(test2, dir = "wide", idvar = "schoolid", timevar = "studentno")
giving:
schoolid student.1 student.2
1 1 1 10
3 2 20 40
5 3 20 NA
3) xtabs xtabs
would also work if there are no students with a score of 0.
xt <- xtabs(score ~ schoolid + studentno, test)
xt[xt == 0] <- NA # omit this step if its ok to use 0 in place of NA
xt
giving:
studentno
schoolid 1 2
1 1 10
2 20 40
3 20