这个函数会做你想做的:
(编辑:根据 OP 的评论更新以反映对问题的更改)
library(tidyr)
# Read in the test data
dat <- read.csv("data_v2.csv", header=F, colClasses="character")
dat
reformat.student.data <- function(dat) {
# To group together the rows belonging to each student
grouprows <- cumsum(dat[,1] == "Name")
# Function to rearrange the data for a single student
f <- function(x) {
Name <- x[2, 1]
y <- unlist(x[, -1])
n <- length(y)
w <- y[seq(1, n-1, 2)]
w <- paste0(1:(nrow(x)/2), "_", w)
v <- y[seq(2, n, 2)]
data.frame(Name, w, v, stringsAsFactors=F)[order(w),]
}
# Use `by` to apply the function to each student
dat2 <- do.call(rbind, by(dat, grouprows, f))
# Use `spread` to reshape the data
dat3 <- tidyr::spread(dat2, w, v)
dat3 # The desired results
}
reformat.student.data(dat)
这是测试数据:
> dat
## V1 V2 V3 V4
## 1 Name Test1 Test2 Test3
## 2 A 1 2 1
## 3 Test1 Test2 Test3
## 4 1 1 2
## 5 Test2 Test3 Test1
## 6 1 2 1
## 7 Name Test2 Test1 Test3
## 8 B 1 2 1
结果如下:
> reformat.student.data(dat)
## Name 1_Test1 1_Test2 1_Test3 2_Test1 2_Test2 2_Test3 3_Test1 3_Test2
## 1 A 1 2 1 1 1 2 1 1
## 2 B 2 1 1 <NA> <NA> <NA> <NA> <NA>
## 3_Test3
## 1 2
## 2 <NA>
编辑:稍微改进了代码。