更改奇怪数据框的格式
Posted
技术标签:
【中文标题】更改奇怪数据框的格式【英文标题】:Changing the format of a weird data frame 【发布时间】:2019-11-22 15:00:14 【问题描述】:我有一个 csv 文件,其中包含一个非常奇怪的表格,我想以正确的方式对其进行格式化。
背景: 学生可以在在线平台上回答问题。这些问题标记为 Test1、Test2、Test3。这三个问题以包的形式呈现,但问题的顺序是随机的。可以是Test1、Test2、Test3或Test2、Test3、Test1等。
我可以将结果下载到 csv 文件中。如果我将结果放到数据框中,它看起来像这样。
分析结果需要的是以下格式:
我正在考虑本地化第一列中每次出现的“姓名”,以将数据框切割成单个数据框,其中每个数据框代表一个学生,如下所示:
对于StudentB,我可以重新排列列,所以看起来像
然后我可以删除按 StudentB 排序的每个学生的列描述并将它们重新组合在一起,给我
虽然我是一名 R 初学者,但我非常有信心找到一种方法来做到这一点,但是如何重新排序 StudentA?
所以我的第一个问题是:哪种方法更好? 第二个问题:回答过多次测试的学生呢?
最好的问候!
【问题讨论】:
你能提供一个可运行的例子吗? 【参考方案1】:这个函数会做你想做的:
(编辑:根据 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>
编辑:稍微改进了代码。
【讨论】:
哇,非常感谢!我可以重现您对您提供的数据集所做的事情。遗憾的是,我注意到我的数据集看起来不像我想象的那样。测试没有以正确的方式编号。而不是 1_Test1 或 2_Test1 两者都被标记为 Test1。是否可以在函数 f 中添加前导数字? 再次感谢您!我不得不更改一些变量,但现在一切都按预期工作。我可能会花一整天的时间弄清楚你的每一行代码是做什么的!以上是关于更改奇怪数据框的格式的主要内容,如果未能解决你的问题,请参考以下文章