从列表中合并并平均每15个data.frames
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从列表中合并并平均每15个data.frames相关的知识,希望对你有一定的参考价值。
我的数据集是一个包含1000个元素类型data.frame(“sportdata”)的列表。列表的每个data.frame元素代表一分钟的数据,并且列的数量和名称完全相同,每个data.frame最多有45个ID(即45行,但在几分钟内,缺少一个或多个ID,所以它可能是例如35行)。我想组合并平均每15个data.frames的完整数据集,将其添加到一个data.frame中并转置data.frame,以便我将ID作为列,每15min的平均SpeedKph作为行。
我的data.frames列表如下所示:
head(sportdata)
[[1]]
ID Distance SpeedKph
1: 1 2247 73
2: 2 2247 73
3: 3 1970 73
4: 4 1964 74
5: 5 1971 73
[[2]]
ID Distance SpeedKph
1: 1 2247 73
2: 2 2247 75
3: 3 1970 73
4: 4 1964 74
5: 5 1971 73
[[3]]
ID Distance SpeedKph
1: 1 2247 73
2: 2 2247 80
3: 3 1970 73
4: 4 1964 74
5: 5 1971 56
我有下面的代码来组合和平均我的列表中的所有data.frames,但我没有找到一种方法来组合和平均每15个元素的列表(即15分钟)并将其添加到一个data.frame中。
dfTotal <- rbindlist(sportdata)[,lapply(.SD,mean), list(ID)]
我希望我理想的输出data.frame看起来像:
#ofData.Frames | 1 | 2 | 3 |...etc.
01-15: 73 74 74
16-30: 75 77 74
31-45: 74 74 79
46-60: 78 72 74
...etc.
在此先感谢您的帮助!
更新很抱歉没有直接这样做,特此我可重复的例子。
my.df1 <- data.frame(ID = c(1:5),
Distance = c(2247,2247,1970,1964,1971),
SpeedKph = c(73,73,74,73,75))
my.df2 <- data.frame(ID = c(1:5),
Distance = c(2247,2247,1970,1964,1971),
SpeedKph = c(73,73,74,73,75))
my.df3 <- data.frame(ID = c(1:5),
Distance = c(2247,2247,1970,1964,1971),
SpeedKph = c(75,70,80,71,83))
my.list <- list(list1 = my.df1, list2 = my.df2, list3 = my.df3)
使用data.table
(您已经使用)的可能解决方案:
DT <- rbindlist(my.list, idcol = 'id')
DT[, grp := (id - 1) %/% 3
][, c(frames = toString(id), lapply(.SD, mean)), by = .(grp, ID), .SDcols = 3:4
][, dcast(.SD, frames ~ ID, value.var = c('Distance','SpeedKph'))]
这使:
frames Distance_1 Distance_2 Distance_3 Distance_4 Distance_5 SpeedKph_1 SpeedKph_2 SpeedKph_3 SpeedKph_4 SpeedKph_5 1: 1, 2, 3 2247 2247.000 1970.000 1964.000 1971 73.66667 72.00000 76.00000 72.33333 77.66667 2: 4, 5, 6 2229 2410.333 1962.667 1964.333 1966 74.66667 73.66667 77.33333 72.33333 77.66667
扩展示例数据:
my.df1 <- data.frame(ID = c(1:5), Distance = c(2247,2247,1970,1964,1971), SpeedKph = c(73,73,74,73,75))
my.df2 <- data.frame(ID = c(1:5), Distance = c(2247,2247,1970,1964,1971), SpeedKph = c(73,73,74,73,75))
my.df3 <- data.frame(ID = c(1:5), Distance = c(2247,2247,1970,1964,1971), SpeedKph = c(75,70,80,71,83))
my.df4 <- data.frame(ID = c(1:5), Distance = c(2247,2137,1948,1965,1971), SpeedKph = c(73,78,74,73,71))
my.df5 <- data.frame(ID = c(1:5), Distance = c(2223,2247,1970,1964,1971), SpeedKph = c(76,73,74,73,79))
my.df6 <- data.frame(ID = c(1:5), Distance = c(2217,2847,1970,1964,1956), SpeedKph = c(75,70,84,71,83))
my.list <- list(my.df1, my.df2, my.df3, my.df4, my.df5, my.df6)
回应评论:
# create some extra example data
my.df4a <- my.df4[-4,]
my.df5a <- my.df5[-c(4,5),]
my.df6a <- my.df6[-c(3,4),]
my.df7 <- my.df4[-c(4:6),]
my.df8 <- my.df5[-c(4:6),]
my.df9 <- my.df6[-c(4:6),]
# make another list of 9 dataframes
my.list2 <- list(my.df1, my.df2, my.df3, my.df4a, my.df5a, my.df6a, my.df7, my.df8, my.df9)
# bind that list together in one data.table
DT2 <- rbindlist(my.list2, idcol = 'dfid')
# do an 'expand join' with 'CJ' and add the original transformation
DT2[CJ(dfid = dfid, ID = ID, unique = TRUE), on = .(dfid, ID)
][, grp := (dfid - 1) %/% 3
][, c(frames = toString(dfid), lapply(.SD, mean, na.rm = TRUE)), by = .(grp, ID), .SDcols = 3:4
][, dcast(.SD, frames ~ ID, value.var = c('Distance','SpeedKph'))]
这给了:
frames Distance_1 Distance_2 Distance_3 Distance_4 Distance_5 SpeedKph_1 SpeedKph_2 SpeedKph_3 SpeedKph_4 SpeedKph_5 1: 1, 2, 3 2247 2247.000 1970.000 1964 1971.0 73.66667 72.00000 76.00000 72.33333 77.66667 2: 4, 5, 6 2229 2410.333 1959.000 NaN 1963.5 74.66667 73.66667 74.00000 NaN 77.00000 3: 7, 8, 9 2229 2410.333 1962.667 NaN NaN 74.66667 73.66667 77.33333 NaN NaN
关于行顺序:
my.df10 <- my.df4
my.df11 <- my.df5
my.df12 <- my.df6
my.list3 <- list(my.df1, my.df2, my.df3, my.df4a, my.df5a, my.df6a, my.df7, my.df8, my.df9, my.df10, my.df11, my.df12)
DT3 <- rbindlist(my.list3, idcol = 'dfid')
DT3[CJ(dfid = dfid, ID = ID, unique = TRUE), on = .(dfid, ID)
][, grp := (dfid - 1) %/% 3
][, c(frames = toString(dfid), lapply(.SD, mean, na.rm = TRUE)), by = .(grp, ID), .SDcols = 3:4
][, dcast(.SD, grp + frames ~ ID, value.var = c('Distance','SpeedKph'))]
这给了:
grp frames Distance_1 Distance_2 Distance_3 Distance_4 Distance_5 SpeedKph_1 SpeedKph_2 SpeedKph_3 SpeedKph_4 SpeedKph_5 1: 0 1, 2, 3 2247 2247.000 1970.000 1964.000 1971.0 73.66667 72.00000 76.00000 72.33333 77.66667 2: 1 4, 5, 6 2229 2410.333 1959.000 NaN 1963.5 74.66667 73.66667 74.00000 NaN 77.00000 3: 2 7, 8, 9 2229 2410.333 1962.667 NaN NaN 74.66667 73.66667 77.33333 NaN NaN 4: 3 10, 11, 12 2229 2410.333 1962.667 1964.333 1966.0 74.66667 73.66667 77.33333 72.33333 77.66667
获得完整数据集后,请尝试以下操作:
将数据帧减少15秒
首先添加一列1:nrow(df)
,我们将使用1:1000
作为这个例子。
require(tidyverse)
DF <- data.frame(mean_speed = sample(40:100, 1000, replace = TRUE))
DF2 <- DF %>%
mutate(index = 1:nrow(.),
group = cut(index, c(seq(0, nrow(.), 15), nrow(.)))) %>%
group_by(group) %>%
mutate(row_num = row_number()) %>%
select(-index) %>%
spread(row_num, mean_speed)
我们最终将行切成15分钟的序列。然后我们将其分组并设置行号。这将为每组提供1:15
。然后我们想取消选择除了小组和平均值之外的所有内容。最后,我们将格式扩展到更广泛。
编辑:给出您的更新信息。我会尝试以下方法:
DF2 <- dfTotal %>%
mutate(group = cut(ID, c(seq(0, nrow(.), 15), nrow(.)))) %>%
group_by(group) %>%
select(-Distance) %>%
spread(ID, SpeedKph)
我不确定的一件事是,在较大的数据帧中ID是1:1000,还是1:15。如果您可以为数据集提供50行,那将有所帮助。如果ID是1:15,您应该能够使用上面的代码。如果它是1:1000,那么你需要添加mutate(row_num = row_number())
以上是关于从列表中合并并平均每15个data.frames的主要内容,如果未能解决你的问题,请参考以下文章
将第N行的NAs插入到data.frames列表中,从列表中插入N行。
<- NULL 在列表上的行为与用于删除数据的 data.frames 的行为