基于与条件的固定时间的时间接近度来子集数据帧

时间:2015-04-23 15:03:22

标签: r

这是我第一次自己设法找到问题的解决方案,使用现有帖子中建议的R代码。所以,感谢所有帮助者,我得到了迄今为​​止所有的帮助。

设计:

我有一个很大的data.frame(大约370万行×15列;让我们称之为df)看起来像这样(为了更清楚我只保留了必要的列示例):

       Site        Date Type  Mesure   .... 
 1   1590041 1998-05-15    P    0.15
 2   1590041 1999-05-04    P    0.18
 3   1590041 2000-05-16    C     3.6
 4   1590041 2001-05-15    I    2.10
 5   1590041 2002-04-17    P    4.30
 6   1590041 2003-09-03    I    0.20
 7   1700224 1999-12-15    P    0.19
 8   1700224 1999-05-08    P    2.12
 9   1700224 2000-05-12    C     1.6
10   1700224 2001-05-15    I    3.10
11   1700224 2003-08-19    P    0.30
12   1700224 2003-09-03    I    2.20
....

对于每个网站,我的样本为Type = "C"Type = "I"Type = "P" Type = "C"就像我的数据集中的引用一样。大多数情况下,每个站点只有1个Type = "C"样本(少数例外有2个Type = "C"样本)。

我想为Type="C"中的每个data.frame样本找到最接近(使用DateType="I"和最近Type="P"个样本的样本,但来自同一个Site

最终目标是通过保留所有data.frame个样本来对我的初始Type="C"进行子集化,但只有Type="P"Type="I"个样本最接近Type="C"来自同一站的样本。

在一位同事的帮助下,我们写道:

 c1 <- df[df$Type=="C",]  
 p1 <- df[df$Type=="P",]  
 i1 <- df[df$Type=="I",]
toto <- by(df, df$Site, FUN = function(y)  
  t(as.data.frame(sapply(y[y$Type == "C", "Date"], function(x) 
    y[y$Type == "P", ][which.min(abs(difftime(x, y[y$Type == "P", "Date"]))), ]))))  
head(toto)
$`1590041`
       Site        Date   Type   Mesure   
V1 "1590041" 1246406400    "P"     0.18       

$`1700224`
       Site        Date   Type   Mesure 
V1 "1700224" 1282694400    "P"     2.12  
...

然后,我重复toto2toto相似但对type = "P"更改type= "I"的操作。

这不是我想要的,但我没有找到更接近我的期望的方法(至少,代码返回正确的Type="P"行)。 我的问题(我不是说我希望我的代码能够产生其他东西,我想改进以下几点):

  • 结果是一个列表(我以后仍可以rbind

  • 我无法找到一种方法同时搜索最接近的Type=P - 样本和Type=I样本(即在单个函数中;目前,我重复相同的程序2次)

  • 我得到了傻瓜&#34; Date的格式,并且不明白为什么。

  • 更重要的是:我使用此代码,通过site询问结果。对于包含2 Type=C个样本(少数情况)的网站,它不起作用。我更愿意询问结果Type="C"示例,但这意味着在代码中添加一个条件,用于查看来自同一Type="P"的{​​{1}}和Type="C"个样本。

理想情况下,代码会返回如下内容:

Site

我必须承认,我已经失去了所有 Site Date Type Mesure .... 2 1590041 1999-05-04 P 0.18 3 1590041 2000-05-16 C 3.6 4 1590041 2001-05-15 I 2.10 8 1700224 1999-05-08 P 2.12 9 1700224 2000-05-12 C 1.6 10 1700224 2001-05-15 I 3.10 ({等等...... 如果有人对我的大[进行子集化并且仅保留所选行(即最接近同一data.frame的{​​{1}}样本)有一些建议,我将不胜感激。

2 个答案:

答案 0 :(得分:1)

这是dplyr使事情变得更容易的一个很好的例子:

df <- read.table(text="       Site        Date Type  Mesure 
 1   1590041 1998-05-15    P    0.15
 2   1590041 1999-05-04    P    0.18
 3   1590041 2000-05-16    C     3.6
 4   1590041 2001-05-15    I    2.10
 5   1590041 2002-04-17    P    4.30
 6   1590041 2003-09-03    I    0.20
 7   1700224 1999-12-15    P    0.19
 8   1700224 1999-05-08    P    2.12
 9   1700224 2000-05-12    C     1.6
10   1700224 2001-05-15    I    3.10
11   1700224 2003-08-19    P    0.30
12   1700224 2003-09-03    I    2.20", stringsAsFactors=FALSE)

df$Date <- as.Date(df$Date)

library(dplyr)

df2 <- df %>% group_by(Site) %>%  
  mutate (Diff = abs(difftime(Date, Date[Type=="C"], units="days"))) %>% 
  group_by(Site, Type) %>% 
  filter(Diff == min(Diff)) %>%
  select(-Diff)

df2
#     Site       Date Type Mesure 
#1 1590041 1999-05-04    P   0.18
#2 1590041 2000-05-16    C   3.60
#3 1590041 2001-05-15    I   2.10 
#4 1700224 1999-12-15    P   0.19 # Your expected result was wrong for this line
#5 1700224 2000-05-12    C   1.60
#6 1700224 2001-05-15    I   3.10

df2是通过Site对数据进行分组创建的,创建一个新的列,其中日期和日期Type == C之间存在绝对差异,然后按Type分组}和Date,并仅过滤每个Type的每个Site的较小差异。

这并不能解决您的重复Type C问题,因为您没有指定要选择哪一个(或至少用作参考)。如果您有该信息,则可以更新代码。例如,如果您在min(Date[Type=="C"])内使用difftime,则会使用最早的Date,但您也可以使用Date[Type=="C"][1]来选择Type C的第一次出现。在这两种情况下,只会保留一个Type C,以便同时调整filter来电。

答案 1 :(得分:1)

sp <- sapply(unique(df$Site), function(X) which(df$Site == X & df$Type == 'P')
      [which.min(abs(difftime(df[df$Site== X & df$Type == 'C',]$Date, 
      df[df$Site== X & df$Type == 'P',]$Date)))])

si <- sapply(unique(df$Site), function(X)  which(df$Site == X & df$Type == 'I')
     [which.min(abs(difftime(df[df$Site== X & df$Type == 'C',]$Date, 
     df[df$Site== X & df$Type == 'I',]$Date)))])

sc <- which(df$Site %in% unique(df$Site) & df$Type == 'C')

df[sort(c(sp, si, sc))]

#    Site       Date Type Mesure
#2  1590041 1999-05-04    P   0.18
#3  1590041 2000-05-16    C   3.60
#4  1590041 2001-05-15    I   2.10
#7  1700224 1999-12-15    P   0.19
#9  1700224 2000-05-12    C   1.60
#10 1700224 2001-05-15    I   3.10

sp包含P类型行的行号,这些行的日期为同一C

Site的{​​{1}}