我有一个包含2列的数据框(我在R中尝试这个)。时间和距离。有70,000行。我想创建一个新的数据帧,其中数据被更大的时隙分箱。例如,将前20毫秒与对应于行1:6的“距离”值之和进行合并。返回带有分箱时间值及其相应距离值的新数据帧。
Time Distance
1 0 0.000
2 0 0.018
3 5 0.030
4 10 0.037
5 15 0.074
6 20 0.039
7 25 0.063
8 30 0.065
9 35 0.063
10 40 0.088
11 45 0.040
12 50 0.038
13 55 0.062
14 60 0.056
...
答案 0 :(得分:1)
这种做法假定您收集数据的方式类似于您的示例。也就是说,你有时间单位以5ms的间隔以均匀的方式上升。
我对前两行感到困惑,因为两者都有Time = 0,但距离不同。我假设时间= 0和距离= 0.018的第2行可能是一个错误?假设你无法在0ms内到达任何地方。
因此我使用了这个df:
Time Distance
1 0 0.000
2 5 0.030
3 10 0.037
4 15 0.074
5 20 0.039
6 25 0.063
7 30 0.065
8 35 0.063
9 40 0.088
10 45 0.040
11 50 0.038
12 55 0.062
13 60 0.056
首先,我摆脱了第一行。
df<-df[-1,]
然后我设置了分箱信息:
bin<-20 # the bin interval in ms
nbins<-max(df$Time) / bin # the number of bins in the data
repeats<-nrow(df)/nbins # how many rows are in each bin (assuming Time is incremental in regular nits)
并添加了一个带有bin信息的变量:
df$bins<- rep(1:nbins, each=repeats)
您现在可以选择任何您想要对数据求和的方式。我目前喜欢dplyr
,因为您可以轻松地对结果做出贡献&#34;
library(dplyr)
df %>%
group_by(bins) %>%
summarise (sumdist=sum(Distance)) %>%
mutate(bins=bins*bin)
最后一行只是将bin号替换为该bin的最后一行&time;给出了这个输出:
bins sumdist
1 20 0.180
2 40 0.279
3 60 0.196
希望这会有所帮助或给你一些想法。当然,如果第二行不是拼写错误,那么我就必须重新考虑事情。
答案 1 :(得分:1)
试试这个:
library(dplyr)
# tbl <- read.table(...) # from above
tbl_df(tbl) %>%
group_by(bin = Time %/% 20) %>%
summarise(Distance = sum(Distance)) %>%
mutate(Time = bin * 20) %>%
select(Time, Distance)
## Source: local data frame [4 x 2]
##
## Time Distance
## 1 0 0.159
## 2 20 0.230
## 3 40 0.228
## 4 60 0.056
必须有一种更优雅的方式来做到这一点。它也可以在没有dplyr
的情况下完成:
ret <- Reduce(rbind.data.frame,
by(tbl, tbl$Time %/% 20,
function(xx) c(xx$Time[1], sum(xx$Distance))))
colnames(ret) <- c('Time', 'Distance')
我个人觉得dplyr解决方案更容易阅读,而且比我的by()
实施快一点:
## microbenchmark(dplyr = { ... }, by = { ... })
## Unit: microseconds
## expr min lq median uq max neval
## dplyr 971.165 1023.264 1058.486 1108.933 3815.682 1000
## by 1203.408 1262.111 1300.818 1354.200 7718.682 1000
答案 2 :(得分:1)
以下内容可能更容易理解,因为它仅使用基本功能:
ddf = structure(list(no = 1:13, time = c(0L, 5L, 10L, 15L, 20L, 25L,
30L, 35L, 40L, 45L, 50L, 55L, 60L), distance = c(0, 0.03, 0.037,
0.074, 0.039, 0.063, 0.065, 0.063, 0.088, 0.04, 0.038, 0.062,
0.056)), .Names = c("no", "time", "distance"), class = "data.frame", row.names = c(NA,
-13L))
ddf
no time distance
1 1 0 0.000
2 2 5 0.030
3 3 10 0.037
4 4 15 0.074
5 5 20 0.039
6 6 25 0.063
7 7 30 0.065
8 8 35 0.063
9 9 40 0.088
10 10 45 0.040
11 11 50 0.038
12 12 55 0.062
13 13 60 0.056
ddf2 = data.frame(time2=numeric(), distance2=numeric())
totaldistance =0
for( i in 1:nrow(ddf)){
totaldistance = totaldistance + ddf[i,"distance"]
if(ddf[i,"time"]%%20==0) {
ddf2[nrow(ddf2)+1,]=c(ddf[i,"time"], totaldistance)
totaldistance=0
}
}
ddf2
time2 distance2
1 0 0.000
2 20 0.180
3 40 0.279
4 60 0.196