【问题标题】:Filter data frame by results from tapply function通过 tapply 函数的结果过滤数据框
【发布时间】:2016-05-31 18:29:53
【问题描述】:

我正在尝试应用我编写的 tapply 函数来过滤数据集。下面是一个示例数据框 (df),用于描述我正在尝试做的事情。

我想在我的数据框中保留 df$Cumulative_Time 的值最接近 14 的行。它应该为 df$ID 中的 每个 因子级别执行此操作(保留行最接近每个 ID 因子的值 14)。

ID  Date    Results TimeDiff    Cumulative_Time
A   7/10/2015   71  0   0
A   8/1/2015    45  20  20
A   8/22/2015   0   18  38
A   9/12/2015   79  17  55
A   10/13/2015  44  26  81
A   11/27/2015  98  37  118
B   7/3/2015    75  0   0
B   7/24/2015   63  18  18
B   8/21/2015   98  24  42
B   9/26/2015   70  30  72
C   8/15/2015   77  0   0
C   9/2/2015    69  15  15
C   9/4/2015    49  2   17
C   9/8/2015    88  2   19
C   9/12/2015   41  4   23
C   9/19/2015   35  6   29
C   10/10/2015  33  18  47
C   10/14/2015  31  3   50
D   7/2/2015    83  0   0
D   7/28/2015   82  22  22
D   8/27/2015   100 26  48
D   9/17/2015   19  17  65
D   10/8/2015   30  18  83
D   12/9/2015   96  51  134
D   1/6/2016    30  20  154
D   2/17/2016   32  36  190
D   3/19/2016   42  27  217

我得到了以下几点:

spec_day = 14  # value I want to compare df$Cumulative_Time to


# applying function to calculate closest value to spec_day
    tapply(df$Cumulative_Time, df$ID, function(x) which(abs(x - spec_day) == min(abs(x - spec_day))))

问题:如何包含这个 tapply 函数作为过滤我的数据框 df 的方法?我是在以正确的方式解决这个问题,还是有一些我没有看到的更简单的方法来完成这个问题?任何帮助将不胜感激 - 谢谢!

【问题讨论】:

  • 如果您想坚持使用 R 基础语言,您可以查看 split(df, df$ID),然后使用 lapply 使用您的方法检索与特定 ID result <- lapply(mysplit, FUN=function(df){df[which()...,]}) 对应的索引。最后将所有过滤后的数据与do.call("rbind", result) 结合起来。我鼓励调查data.table options
  • 谢谢@EricLecoutre!我记得读过关于 split() 的文章,所以我也会尝试这种方法!

标签: r subset tapply


【解决方案1】:

这里有一个办法,注意我没有用tapply

spec_day <- 14
new_df <- do.call('rbind', 
            by(df, df$ID, 
            FUN = function(x) x[which.min(abs(x$Cumulative_Time - spec_day)), ]
              ))
new_df

  ID      Date Results TimeDiff Cumulative_Time
A  A  8/1/2015      45       20              20
B  B 7/24/2015      63       18              18
C  C  9/2/2015      69       15              15
D  D 7/28/2015      82       22              22

which.min(及其兄弟which.max)是一个非常有用的函数。

【讨论】:

  • 谢谢@bouncyball!我想我明白 which.min--感谢您向我指出此功能以及向我介绍解决此问题的另一种方法!
【解决方案2】:

这是使用data.table 的更简洁和更快的替代方案:

library(data.table)
setDT(df)[, .SD[which.min(abs(Cumulative_Time - 14))], by = ID]
#   ID      Date Results TimeDiff Cumulative_Time
#1:  A  8/1/2015      45       20              20
#2:  B 7/24/2015      63       18              18
#3:  C  9/2/2015      69       15              15
#4:  D 7/28/2015      82       22              22

【讨论】:

  • 谢谢,@mtoto!我喜欢这个简洁。理解代码在做什么也相当直观!
猜你喜欢
  • 2014-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-15
  • 1970-01-01
  • 2017-06-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多