【发布时间】:2016-12-29 09:08:28
【问题描述】:
我有一台设备的输出数据。不幸的是,输出数据组织得不是很好,我一直在用 R 编写代码来分解它。本质上,数据是粘贴到一个长文档中的每个主题的单独信息列表(基本描述信息,以及每个时间间隔的两个不同测量 A 和 B 的原始数据)。例如:
Date: 01/01/2016
Time: 12:00:00
Subject: Subject1
A:
1: 1 2 4 1
2: 2 1 2 3
3: 1 0 2 7
B:
1: 2 3 0 1
2: 4 1 1 2
3: 3 5 2 8
Date: 01/01/2016
Time: 12:00:00
Subject: Subject2
A:
1: 8 2 0 1
2: 9 1 2 7
3: 1 6 2 7
B:
1: 2 3 2 0
2: 6 7 1 2
3: 3 3 2 4
我使用 split(seq_along)、for-loops 和 do.call(主要基于 this stack overflow question 和 this blog post)在 R 中编写了一个有效但不是很优雅的代码。
# First read text file in as a character vector called ‘example’
scan("example_file.txt", what="character", strip.white=T, sep="\n") -> example
# Separate the header text (before the colon) from the proceeding data
# and make that text name the components of the vector
regmatches(example, regexpr(example, pattern="[[:alnum:]]+:", useBytes = F)) -> names(example)
gsub(example, pattern="[[:print:]]+: ", replacement="", useBytes = F)-> example.2
# Then, split character vector into a list based on how many lines are
# dedicated to each subject (in this example, 11 lines); based on SE
# answer cited above
strsplit(example.2, "([A-Z]:)") -> example.3
split(as.list(example.3), ceiling(seq_along(example.2)/11)) -> example.4
# Use a for-loop to systematically add the data together for subjects 1
# and 2 for time interval 1, using the method detailed from a blog post
# (cited above)
my.list <- list()
for(i in 1:2){
strsplit(as.character(example.4[[i]][5]), split="[[:blank:]]+") -> A
strsplit(as.character(example.4[[i]][9]), split="[[:blank:]]+")-> B
as.vector(c(as.character(example.4[[i]][3]), "A", unlist(A))) -> A_char
as.vector(c(as.character(example.4[[i]][3]), "B", unlist(B))) -> B_char
paste(as.character(example.4[[i]][3]), "Measure_A") -> a_name
paste(as.character(example.4[[i]][3]), "Measure_B") -> b_name
my.list[[a_name]] <- A_char
my.list[[b_name]] <- B_char
}
final.data <- do.call(rbind, my.list)
as.data.frame(final.data) -> final.data
names(final.data) <- c("Subject", "Measure", "V1", "V2", "V3", "V4")
我可以使用我的代码(例如,上面的“1: 1 2 4 1”和“1: 2 3 0 1”行)在所有受试者中提取 A 和 B 的单个时间间隔的数据并放入将所有信息放在一个数据框中。当我想为 所有 的时间间隔而不只是一个时间间隔执行此操作时,哪里会变得混乱。如果不为每个时间间隔运行单独的 for 循环,我无法弄清楚如何做到这一点。我尝试在 for 循环中执行 for 循环,但没有奏效。我也不知道如何使用 apply() 类型的函数来做到这一点。
如果我只有 3 个时间间隔,按照这个例子,这个问题不会那么糟糕,但我的实际数据要长得多。任何关于更优雅和简洁方法的建议都将不胜感激!
附:我知道上面代码给出的最终数据框有多余的行名。但是,这是确保最终数据框的主题和度量信息与我应用于早期 R 对象的标签一致的有用方法。
【问题讨论】:
-
您是使用
>来实现块引用效果还是数据本身在行首有>?而且,行之间有空格吗? -
我只使用了
>的块引用效果。实际数据没有这些。行之间没有空格,但由于strip.white=T参数,我的代码仍应使用空行。 -
不要使用块引用效果 - 格式为代码。会清晰很多。
-
我将其重新格式化为代码;感谢您的建议