【问题标题】:Date Difference within a group in R and creating a new column based on certain conditionsR中组内的日期差异并根据某些条件创建新列
【发布时间】:2015-05-27 22:45:16
【问题描述】:

在创建新数据框时需要帮助,该数据框将包含名为 Name 和 Value_2 的列。 现有数据框包括名称、日期和值_1 等列。将使用遵循条件的现有数据框创建新数据框。下面是现有的数据框,以便更清楚:-

Name    Date       Value_1
A       9/28/2011  12345
A       1/8/2012   23456
A       6/3/2013   78910
B       10/4/2010  438504
B       10/14/2013 439587
C       8/22/2013  436096
D       4/20/2010  3258043
D       3/24/2013  968347
D       7/8/2013   954733
D       8/19/2013  438578

在组名 A 中,第一次测试在 2011 年 9 月 28 日进行,value_1 为 12345,最后一次测试在 2013 年 6 月 3 日进行,value_1 为 23456。因此,新数据框中的 value_2遵循一个条件来检查 log10(12345) -log10(23456) >=2 并将组名 A 分类为 ne 数据帧的 value_2 列中的 Yes/No。其他组也需要遵循类似的条件。以下是供您参考的所需输出:-

Name    Value_2
A       No
B       Yes
C       Yes
D       No

这里的Value_2遵循log10(first test date value_1)-log10(last test date value_1)>=2的条件。

【问题讨论】:

  • 为什么 C 是?第一个测试也是最后一个测试的特殊条件是什么?实际上我得到了不同的结果。
  • 6/3/2013 中的值是78910,而不是23456
  • 看着tapply(dat$Value_1,dat$Name,log10)我看不出你有什么不同>=2
  • @thelatemail 我生成的所需数据框是一个随机示例,但不是遵循日志条件的输出。对于 C,如果只进行了一行或一个测试,我们可以遵循 log(436096)-log(436096) 的规则,它等于 0,因此 value_2 的输出为“No”跨度>
  • @thelatemail 我们可以忽略行,其中只进行了一项测试。在最后阶段,我们可以直接将这些值归为“否”。

标签: r


【解决方案1】:

这是一个split-apply-combine 问题,它建议像tapply by aveaggregate 以及扩展包plyrdplyr 甚至data.table 这样的函数。在这种情况下,一个简单的tapplyaggregate 可以根据您想要的输出格式工作(使用@Robert 的Data):

Data <- Data[order(Data$Name, as.Date(Data$Date, "%m/%d/%Y")),]

tapply(log10(Data$Value_1), Data$Name, function(x) head(x,1) - tail(x,1) >= 2)
#    A     B     C     D 
#FALSE FALSE FALSE  TRUE 

aggregate(log10(Data["Value_1"]), Data["Name"], FUN=function(x) head(x,1) - tail(x,1) >= 2)
#  Name Value_1
#1    A   FALSE
#2    B   FALSE
#3    C   FALSE
#4    D    TRUE

【讨论】:

    【解决方案2】:

    你可以试试这个:

    Data <- read.table(textConnection("
    Name    Date       Value_1
    A       9/28/2011  12345
    A       1/8/2012   23456
    A       6/3/2013   78910
    B       10/4/2010  438504
    B       10/14/2013 439587
    C       8/22/2013  436096
    D       4/20/2010  3253043
    D       3/24/2013  968347
    D       7/8/2013   954733
    D       8/19/2013  438"), stringsAsFactors=FALSE,head=TRUE)
    
    Data$Date=as.Date(Data$Date,"%m/%d/%Y")
    Names=unique(Data$Name)
    sdf=lapply(Names,function(x)Data[Data$Name == x,])
    Value_2=sapply(sdf,function(dt){
      rx=dt$Date%in%range(dt$Date)
      if (length(rx)==1) return("No") else
      return(ifelse(-diff(log10(dt$Value_1[rx]))>=2,"Yes","No"))
    })
    data.frame(Names,Value_2)
    
      Names Value_2
    1     A      No
    2     B      No
    3     C      No
    4     D     Yes
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-17
      • 1970-01-01
      • 2019-09-21
      • 2017-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多