2016-12-06 120 views
-1

我對R相對較新,並且努力在R中「矢量化」所有代碼。儘管我很欣賞這是正確的方法。將觀察值設置爲R中該觀察值的最小值

我需要在數據框中設置一個值作爲ID的最小時間。以下作品完美

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 

ID isTrue RealTime MinTime 
1 TRUE  16 
1 FALSE 8 
1 TRUE  10 
2 TRUE  7 
2 TRUE  30 
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 
     } 
    } 
} 

我應該如何正確地做到這一點?我把它用於或做循環不是在R最好的方式。我一直在看apply()和aggregate.data.frame()函數,但不知道如何做到這一點。有人能指引我朝着正確的方向嗎?非常感激!!

+0

看看'ave'。 – lmo

+0

謝謝,第一次嘗試是接近。 df $ MinTime <-ave(df $ RealTime,df $ ID,FUN = min)。但是,我怎樣才能讓它取得那些isTrue = TRUE的呢? – user2535309

+0

df $ MinTime <-ave(df $ RealTime,df $ ID,df $ isTrue,FUN = min) df $ MinTime <-ifelse(df $ isTrue,df $ MinTime,NA)。這會返回一大堆警告,但會起作用。謝謝! – user2535309

回答

0

有人建議和快雖然它返回一噸警告:

df$MinTime<-ave(df$RealTime,df$ID, df$isTrue, FUN = min) 
df$MinTime<-ifelse(df$isTrue, df$MinTime,NA). 
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,如果你打算做大量的數據幀操作的。使用AVE()函數和以下工作

+0

謝謝。我會深入dplyr庫,因爲它看起來很有幫助。正如我在下面從別人的建議中發佈的,ave()函數也適用於這個ID以及isTrue – user2535309

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") 
0

在問題中的代碼可以通過做這一切在R中SQL或全部被簡化(適當地向量化),而不是一半一半。已經有一些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