在给定另一列中的对应连续值的情况下找到一列中的值的中值是相等的数

时间:2013-10-10 18:08:01

标签: r median

我在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]])

这不起作用。这样做有人有任何答案吗?

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

1 个答案:

答案 0 :(得分:2)

我想到了两种解释。

解释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), ])