- bounty将在5天后过期**。回答此问题可获得+100声望奖励。socialresearcher希望引起更多人关注此问题。
我有来自多个参与者的数据,我正尝试使用一组文件中的信息来聚合另一组文件中的数据。
我有一个包含四列的数据文件(videodata.csv
):Event.Type
(视频名称)、Name
(开始或结束)、Row
(行号)和Source
(参与者ID代码)。设置如下:
videodata <- data.frame(
Event.Type = c("Movie1", "Movie1", "Movie2", "Movie2", "Movie3", "Movie3",
"Movie1", "Movie1", "Movie2", "Movie2", "Movie3", "Movie3",
"Movie1", "Movie1", "Movie2", "Movie2", "Movie3", "Movie3"),
Name = c("start", "end", "start", "end","start", "end",
"start", "end", "start", "end","start", "end",
"start", "end", "start", "end","start", "end"),
Row = c(1, 10, 11, 20, 21, 30,
8, 16, 19, 28, 1, 7,
2, 8, 21, 26, 9, 20),
Source = c("012", "012", "012", "012", "012", "012",
"013", "013", "013", "013", "013", "013",
"014", "014", "014", "014", "014", "014")
)
我有像80个参与者,所以他们每个人都有另一个csv格式的数据文件(id_data.csv
),有两列:time
和score
。每行对应一秒,因此time
列简单地从1编号到大约1,800或其他数字。score
是0
或1
的二进制代码。对于参与者012、013和014,数据如下所示:
`012_data` <- data.frame(
time = c(1:30),
score = c(0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
)
`013_data` <- data.frame(
time = c(1:30),
score = c(0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
)
`014_data` <- data.frame(
time = c(1:30),
score = c(0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
)
我想使用来自videodata.csv
的信息来分割id_data.csv
,并将它们保存到与Event.Type
对应的单独文件中。
具体来说,我将在videodata.csv
文件中查找id号。对于给定的id号,我将从第一个Event.Type
开始(例如电影1)并找到开始row
和结束row
。我将使用此信息转到该ID号的数据文件,选择score
的那些行,并将它们保存到名为movie1.csv
的文件中。我将对每个参与者重复,直到movie1.csv
包含所有参与者的数据。
例如,对于参与者012,我希望将id_data.csv
文件分成三个块,分别对应于Movie1、Movie2和Movie3。为此,我将:
1.我将选择行1 - 10(基于Row
,Row
表示Start和End),方法是向上舍入到最接近的行号
1.将score
列保存到名为Movie1的文件中,列标题012
来自Source
列
1.对参与者013
重复上述步骤,并将其score
列追加到上一行旁边。
1.然后对参与者014重复,依此类推,直到80。Movie1
的结果文件可能如下所示:
它包括行1 - 10(对于012)、行8 - 16(对于013)和行2 - 8(对于014)中的score
值。
然后,我将拥有另一个对应于Movie2的文件(通过选择第11 - 20、19 - 28和21 - 26行),依此类推,每个参与者的ID可能有稍微不同的行数。
这超出了我的技能,我将感谢任何帮助,我如何才能完成这一点。谢谢!
3条答案
按热度按时间wnvonmuf1#
由于我假设每个_data.csv文件中的行数可能不同,因此我假设按以下方式合并数据:
请注意,这里是一个列表而不是 Dataframe ,因为数据结构和行计数可能会有变化。在应用于
list.files
的lapply
函数中阅读文件时可以达到同样的效果。然后我们用这些文件中的数据创建“长”数据.frame。
所有这些步骤都可以在文件上传时完成。
dl
较长,因此便于进一步操作:其余所有工作都在一根管道中完成:
您可以看到逐步执行管道的中间结果。管道返回以下输出:
此代码的另一个优点是,它不包含对电影名称的任何引用,因此可以像其他答案中那样无需修改地进行缩放。它对所选项目数量的差异具有鲁棒性(参见电影1 == 10和电影3 == 12中的元素数量)。如果012的元素数量小于右列013、014等的元素数量,它也将正常工作
disbfnqx2#
假设您的id数据位于目录
data\id
中,并且它们都具有相同的2列time
和score
,我们可以使用readr::read_csv()
一次读取所有这些文件,同时指定id
参数,该参数将文件路径保存为一列。然后,我们可以拆分该文件路径,只保留我们想要的部分,以获得与视频数据匹配的Source
列。然后,我们可以连接
Source
列上的数据,但必须在对两列进行宽透视之后。连接好数据后,我们可以对它们进行长透视,并通过使用start和end参数查找时间来定义一个新的Event.Type
列。最后,我们只选择所需的列,并再次对它们进行宽透视,以获得所需的输出。这将仍然包含所有的电影,但您可以轻松地添加一个
dplyr::filter(Event.Type == "Movie1")
来获得唯一的文件。更新:我的更新答案从@asd-tm得到了启发。他们的答案总体上更好,但也许你可以使用两者的一些信息,比如从我这里阅读文件,从他们那里清理数据。
5vf7fwbs3#
我设法生成了你想要的文件。请检查代码中的注解以获得更深入的解释。
我认为最后一个代码块(双循环)在时间上可能不是最有效的解决方案,但它是我能想到的“最干净”的解决方案。有时候为了易于理解而牺牲一些性能会更好。