You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言:将DataFrame转换为按卡片、学生分层的嵌套列表

数据格式(txt格式)

Time ; Source ; Action
YYYY-MM-DD ; Card Biology ; Reading succesful 
YYYY-MM-DD ; Student 1 ; initialised 
YYYY-MM-DD ; Book 1 ; first check out
YYYY-MM-DD ; Book 2 ; Second check out
YYYY-MM-DD ; Book 3 ; check in
YYYY-MM-DD ; Student 2 ; initialised 
YYYY-MM-DD ; Book 1 ; first check out
YYYY-MM-DD ; Book 2 ; Second check out
YYYY-MM-DD ; Book 3 ; check in
YYYY-MM-DD ; Card Mathematics; Reading succesful 
YYYY-MM-DD ; Student 2 ; initialised 
YYYY-MM-DD ; Book 1 ; first check out
YYYY-MM-DD ; Book 2 ; Second check out
YYYY-MM-DD ; Book 3 ; check in
YYYY-MM-DD ; Card Biology ; Reading succesful 
YYYY-MM-DD ; Student 1 ; initialised 
YYYY-MM-DD ; Book 1 ; first check out
YYYY-MM-DD ; Book 2 ; Second check out
YYYY-MM-DD ; Book 3 ; check in
YYYY-MM-DD ; Card Biology ; Reading succesful 
YYYY-MM-DD ; Student 1 ; initialised 
YYYY-MM-DD ; Book 1 ; first check out
YYYY-MM-DD ; Book 2 ; Second check out
YYYY-MM-DD ; Book 3 ; check in
YYYY-MM-DD ; Card History ; Reading succesful 
YYYY-MM-DD ; Student 1 ; initialised 
YYYY-MM-DD ; Book 1 ; first check out
YYYY-MM-DD ; Book 2 ; Second check out
YYYY-MM-DD ; Book 3 ; check in
YYYY-MM-DD ; Book 1 ; first check out
YYYY-MM-DD ; Book 2 ; Second check out
YYYY-MM-DD ; Book 3 ; check in
YYYY-MM-DD ; Card Biology ; Reading succesful 
YYYY-MM-DD ; Student 1 ; initialised 
YYYY-MM-DD ; Book 1 ; first check out
YYYY-MM-DD ; Book 2 ; Second check out
YYYY-MM-DD ; Book 3 ; check in

需求说明

  • 先将DataFrame按Action列值为"Reading succesful"的行分割为对应卡片的子列表;
  • 再将每个卡片子列表按Action列值为"initialised"的行分割为对应学生的子列表;
  • 每个学生子列表需包含对应书籍记录,理想状态下附带卡片及学生自身的Time和Action信息;
  • 期望最终数据结构为:
test$
[[card xxx]]$
[[Student 1]], [[Student 2]], etc

[[card yyy]]
[[Student 1]], [[Student 2]], etc

已尝试的代码

test <- split(i, cumsum(test$`b`$Text == "Reading succesful"))

为列表命名的代码:

for (a in test) {
  names(test)<-sapply(test, `[[`, 1,2)
}

但后续循环分割学生子列表的操作未成功,寻求解决方案。

解决方案

步骤1:读取并预处理数据

先确保数据正确读入为DataFrame,处理分隔符和多余空格:

# 读取数据(如果是本地文件,替换为read.delim("你的文件路径", sep = ";", strip.white = TRUE))
df <- read.delim(text = "Time ; Source ; Action
YYYY-MM-DD ; Card Biology ; Reading succesful 
YYYY-MM-DD ; Student 1 ; initialised 
YYYY-MM-DD ; Book 1 ; first check out
YYYY-MM-DD ; Book 2 ; Second check out
YYYY-MM-DD ; Book 3 ; check in
YYYY-MM-DD ; Student 2 ; initialised 
YYYY-MM-DD ; Book 1 ; first check out
YYYY-MM-DD ; Book 2 ; Second check out
YYYY-MM-DD ; Book 3 ; check in
YYYY-MM-DD ; Card Mathematics; Reading succesful 
YYYY-MM-DD ; Student 2 ; initialised 
YYYY-MM-DD ; Book 1 ; first check out
YYYY-MM-DD ; Book 2 ; Second check out
YYYY-MM-DD ; Book 3 ; check in
YYYY-MM-DD ; Card Biology ; Reading succesful 
YYYY-MM-DD ; Student 1 ; initialised 
YYYY-MM-DD ; Book 1 ; first check out
YYYY-MM-DD ; Book 2 ; Second check out
YYYY-MM-DD ; Book 3 ; check in
YYYY-MM-DD ; Card Biology ; Reading succesful 
YYYY-MM-DD ; Student 1 ; initialised 
YYYY-MM-DD ; Book 1 ; first check out
YYYY-MM-DD ; Book 2 ; Second check out
YYYY-MM-DD ; Book 3 ; check in
YYYY-MM-DD ; Card History ; Reading succesful 
YYYY-MM-DD ; Student 1 ; initialised 
YYYY-MM-DD ; Book 1 ; first check out
YYYY-MM-DD ; Book 2 ; Second check out
YYYY-MM-DD ; Book 3 ; check in
YYYY-MM-DD ; Book 1 ; first check out
YYYY-MM-DD ; Book 2 ; Second check out
YYYY-MM-DD ; Book 3 ; check in
YYYY-MM-DD ; Card Biology ; Reading succesful 
YYYY-MM-DD ; Student 1 ; initialised 
YYYY-MM-DD ; Book 1 ; first check out
YYYY-MM-DD ; Book 2 ; Second check out
YYYY-MM-DD ; Book 3 ; check in", sep = ";", strip.white = TRUE)

步骤2:按卡片分割数据

标记卡片分组并分割,同时给子列表命名为对应卡片名称:

# 标记每个卡片组:每遇到"Reading succesful"就开启新组
df$card_group <- cumsum(df$Action == "Reading succesful")

# 分割为卡片子列表
card_list <- split(df, df$card_group)

# 给卡片子列表命名为对应的卡片名称
names(card_list) <- sapply(card_list, function(x) x$Source[1])

步骤3:按学生分割每个卡片子列表

遍历每个卡片子列表,分割为学生子列表,同时保留卡片信息:

# 处理每个卡片子列表,生成学生子列表
final_list <- lapply(card_list, function(card_df) {
  # 标记学生组:从第二行开始,每遇到"initialised"就开启新组,第一行卡片记录归为0组
  student_group <- c(0, cumsum(card_df$Action[-1] == "initialised"))
  card_df$student_group <- student_group
  
  # 分割为学生子列表,排除0组(卡片记录)
  student_list <- split(card_df, card_df$student_group)[-1]
  
  # 给学生子列表命名为对应学生名称
  names(student_list) <- sapply(student_list, function(x) x$Source[which(x$Action == "initialised")])
  
  # 给每个学生子列表添加卡片元信息(可选,方便后续调用)
  student_list <- lapply(student_list, function(student_df) {
    attr(student_df, "card_info") <- card_df[1, ]
    student_df
  })
  
  return(student_list)
})

验证结果

查看最终结构和内容:

# 查看Card Biology下的Student 1记录
final_list[["Card Biology"]][["Student 1"]]

# 查看该学生对应的卡片信息
attr(final_list[["Card Biology"]][["Student 1"]], "card_info")

内容的提问来源于stack exchange,提问作者Romeo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 22:44:53