3

我有一个在 R 中看起来像这样的数据框:

Date | Time | value  
A  | 1  | 3       
A  | 1  | 6     
A  | 2  | 4  
A  | 3  | 3  
A  | 4  | 2  
A  | 5  | 7  
B  | 1  | 6       
B  | 2  | 5  
B  | 2  | 3  
B  | 2  | 4  
B  | 3  | 2  
B  | 5  | 3  
B  | 6  | 4  
... 

如果第二列中的数字在连续行中相等,我的目标是找到第三列中数字的中位数。即,如果它们同时出现,则取值的中值,并为相应的时隙替换该中值。

所以我的目标是输出:

A  | 1  | median (3,6)       
A  | 2  | 4  
A  | 3  | 3  
A  | 4  | 2  
A  | 5  | 7  
B  | 1  | 6       
B  | 2  | median (3,4,5)   
B  | 3  | 2  
B  | 5  | 3  
B  | 6  | 4  
... 

由于数据集很大,我拼命地避免循环。我遇到的主要问题是分别收集值。到目前为止,这是我所拥有的:

#First find consecutive time slots that are equal:
timeslots_equal<-which(diff(data_RAW$TIME)==0)

coordinates_placesholder <- sort(c(as.vector(timestamp_equal_coordinates), as.vector(timestamp_equal_coordinates)+1))

coordinates_placesholder2  <-  coordinates_placesholder[-c(which(diff(coordinates_placesholder)==0), which(diff(coordinates_placesholder)==0) +1)]

 #The following matrix are the coordinates in the value vector with equal time slots
 matrix_ranges<-t(matrix(coordinates_placesholder2,2))

matrix_ranges对于上面的示例,如下所示:

1 | 2  
8 | 10  

然后我尝试应用类似的东西

median(data_RAW$Value[matrix_ranges[,1]:matrix_ranges[,2]])

这没有用。有人对此有任何答案吗?

还有比我上面做的更简单的方法吗?

4

1 回答 1

3

我想到了两种解释。

解释1:重要的是“日期”+“时间”的组合,而不是连续重复。在这种情况下,只需使用aggregate(或您最喜欢的聚合函数或包,如“data.table”)。

aggregate(value ~ Date + Time, mydf, median)
#    Date Time value
# 1     A    1   4.5
# 2     B    1   6.0
# 3     A    2   4.0
# 4     B    2   4.0
# 5     A    3   3.0
# 6     B    3   2.0
# 7     A    4   2.0
# 8     A    5   7.0
# 9     B    5   3.0
# 10    B    6   4.0

解释2:连续重复重要。在这种情况下,您需要另一个“分组”变量。为此,我们可以使用rle. 之后,聚合步骤几乎相同。

RLE <- rle(DF$Time)$lengths
RLE <- rep(seq_along(RLE), RLE)
aggregate(value ~ Date + Time + RLE, DF, median)
#    Date Time RLE value
# 1     A    1   1   4.5
# 2     A    2   2   4.0
# 3     A    3   3   3.0
# 4     A    4   4   2.0
# 5     A    5   5   7.0
# 6     B    1   6   6.0
# 7     B    2   7   4.0
# 8     B    3   8   2.0
# 9     B    5   9   3.0
# 10    B    6  10   4.0
# 11    A    1  11   3.0
# 12    B    3  12   2.0

为了他人的利益,这里有一些可重复的数据:mydfDF。(DF只是mydf重复了几行。)

mydf <- structure(list(Date = c("A", "A", "A", "A", "A", "A", "B", "B", 
        "B", "B", "B", "B", "B"), Time = c(1L, 1L, 2L, 3L, 4L, 5L, 1L, 
        2L, 2L, 2L, 3L, 5L, 6L), value = c(3L, 6L, 4L, 3L, 2L, 7L, 6L, 
        5L, 3L, 4L, 2L, 3L, 4L)), .Names = c("Date", "Time", "value"), 
        class = "data.frame", row.names = c(NA, -13L))
DF <- rbind(mydf, mydf[c(1, 1, 11, 11), ])
于 2013-10-10T18:43:08.150 回答