将观察值设置为R中该观测值的最小值

时间:2016-12-06 20:48:17

标签: r

我对R来说比较新,并且在R中“渲染”我的所有代码都很困难。尽管我很欣赏这是正确的方法。

我需要在数据框中设置一个值作为ID的最短时间。

ID  isTrue  RealTime  MinTime
1    TRUE     16
1    FALSE    8
1    TRUE     10
2    TRUE     7
2    TRUE     30
3    FALSE    3

要变成:

ID  isTrue  RealTime  MinTime
1    TRUE     16        10
1    FALSE    8         
1    TRUE     10        10
2    TRUE     7         7
2    TRUE     30        7
3    FALSE    3

以下作品完美无缺。但是,运行需要10分钟,这并不理想:

for (i in 1:nrow(df)){

    if (df[i,'isTrue']) {
      prevTime <- sqldf(paste('Select min(MinTime) from dfStageIV where ID =',df[i,'ID'],sep=" "))[1,1]
      if  (is.na(prevTime) | is.na(df[i,'MinTime']) | df[i,'MinTime'] < prevTime){
        df[i,'MinTime']<-dfStageIV[i,'RealTime']
      } else {
        dfStageIV[i,'MinTime']<-prevTime
      }
    }
}

我该如何正确地做到这一点?我认为使用for或do循环不是R中的最佳方法。我一直在查看apply()和aggregate.data.frame()函数,但无法理解如何执行此操作。有人能指出我正确的方向吗?非常感谢!!

4 个答案:

答案 0 :(得分:2)

以下是使用avepmaxis.na的双行基础R解决方案。

# calculate minimum for each ID, excluding FALSE instances
df$MinTime <- ave(pmax(df$RealTime, (!df$isTrue) * max(df$RealTime)), df$ID, FUN=min)
# turn FALSE instances into NA
is.na(df$MinTime) <- (!df$isTrue)

返回

df
  ID isTrue RealTime MinTime
1  1   TRUE       16      10
2  1  FALSE        8      NA
3  1   TRUE       10      10
4  2   TRUE        7       7
5  2   TRUE       30       7
6  3  FALSE        3      NA

在第一行中,pmax用于构造观察的向量,如果df$isTrue为TRUE或data.frame中的最大实时值。这个新向量用于最小计算。 FALSE值在第二行中设置为NA。

数据

df <- read.table(header=T, text="ID  isTrue  RealTime
1    TRUE     16
1    FALSE    8
1    TRUE     10
2    TRUE     7
2    TRUE     30
3    FALSE    3")

答案 1 :(得分:0)

dplyr链的速度应该快得多。在这里,我们按ID和组对数据框进行分组,并在组级别获取最小值。然后我们可以再次取消组合,只需删除F最小值。

library(dplyr)
df %>% 
   group_by(ID, isTrue) %>% 
   mutate(Min.all = min(RealTime)) %>% 
   ungroup() %>%
   transmute(ID, isTrue, RealTime, MinTime = ifelse(isTrue == T, Min.all, ""))

输出:

# A tibble: 6 × 4
     ID isTrue RealTime MinTime
  <int>  <lgl>    <int>   <chr>
1     1   TRUE       16      10
2     1  FALSE        8        
3     1   TRUE       10      10
4     2   TRUE        7       7
5     2   TRUE       30       7
6     3  FALSE        3        

如果你要进行大量的数据帧操作,我真的建议你熟悉dplyr

答案 2 :(得分:0)

有人建议使用ave()函数和以下工作并且速度很快,尽管它会返回大量警告:

df$MinTime<-ave(df$RealTime,df$ID, df$isTrue, FUN = min) 
df$MinTime<-ifelse(df$isTrue, df$MinTime,NA). 

答案 3 :(得分:0)

问题中的代码可以通过SQL中的全部内容或R中的所有内容(适当的矢量化)而不是一半来简化。已经有一些R解决方案,所以这里有一个SQL解决方案,表明问题相当于聚合自定义自联接。

library(sqldf)
sqldf("select a.*, min(b.RealTime) minRealTime
       from df a 
       left join df b on a.ID = b.ID and a.isTRUE and b.isTRUE
       group by a.rowid")

,并提供:

  ID isTrue RealTime minRealTime
1  1   TRUE       16          10
2  1  FALSE        8          NA
3  1   TRUE       10          10
4  2   TRUE        7           7
5  2   TRUE       30           7
6  3  FALSE        3          NA