2016-02-08 30 views
2

需要您的幫助來解決循環問題;r:何時使用if else循環與函數

示例數據:

data2 <- structure(list(a = c(101, 102, 103, 104, 105, 106, 107, 108,109,110), 
         b = c(1,1,1,1,2,2,3,4,4,4), 
         c = c(4, 4, 4, 4, 2, 2, 1, 3,3,3)), 
      .Names = c("ID", "Band", "Group_qty"), row.names = c(NA, 10L), class = "data.frame") 

實例所需的輸出:

Output <- structure(list(a = c(101, 102, 103, 104, 105, 106, 107, 108, 109, 110), 
          b = c(1,1,1,1,2,2,3,4,4,4), 
          c = c(4,4,4,4,2,2,1,3,3,3), 
          d = c(102,103,104,103,"Class B","Class B","Class A",109,110,109)), 
        .Names = c("ID", "Band", "Group_qty","NewID"), row.names = c(NA, 10L), class = "data.frame") 

草案如果else語句: 注:這是行不通的。

data2$NewID <- 
    for(i in 1:length(data2$ID)) 
    { 
    ifelse(data2$[i,3] == 1, "Class A", ifelse(data2[i,3] == 2, "Class B", ifelse(data2[i,2] == data2[i+1,2], data2[i+1,1], data2[i-1,1]))) 
    } 

問:

如何創建一個工作循環或功能,我可以dplyr使用。 規則:

  1. 如果Group_qty = 1;輸出= A類

  2. 如果Group_qty = 2;輸出= B類

  3. 否則,請檢查該樂隊是否與下一行的樂隊相匹配。

    • IF YES,輸出=下一行的ID
    • 如果沒有,輸出=前行的ID
  4. 一旦我們達到循環的最後一排 - 我們不會有一排+ 1。在這種情況下:輸出=上一行的ID。

  5. 可以使用dplyr &變異來解決這個問題。如果是的話,願意將其作爲可能的答案。

感謝,

+1

我改變了對你的循環字面上兩件事情1)'sapply'返回結果和2)'%在%'代替=='來更好地處理NAs,絕對沒有理由爲這個任務引入一個包'sapply(1:length(data2 $ ID),function(i)ifelse(data2 [i,3]%in %1,「A類」,ifelse(data2 [i,3]%in%2,「Class B」,ifelse(data2 [i,2]%in%data2 [i + 1,2],data2 [i + 1,1],data2 [i-1,1]))))' – rawr

+2

@rawr - 你可以做到(數據2 $ Band,-1),NA); lband < - data2 $ Band == tband; data2 $(數據2 $ NewID < - NA; tband < - c NewID [which(lband)] < - c(tail(data2 $ ID,-1),NA)[which(lband)]; data2 $ NewID [which(!數據2 $新ID [數據2 $新ID]] - 尾(數據2 $ ID,2)[1 ]; data2 $ NewID [data2 $ Group_qty == 1] < - 「Class A」; data2 $ NewID [data2 $ Group_qty == 2] < - 「Class B」' – thelatemail

+0

@thelatemail它的純度使它更美麗 – rawr

回答

2

我們可以使用data.table。將'data.frame'轉換爲'data.table'(setDT(data2)),按'Band'分組,if組中的元素數大於1(.N >1),我們使用shifttype='lead'獲得後續的'ID '爲每個組或else保留'ID'以創建'NewID'列。然後,根據條件,我們使用ifelse替換'NewID'中對應於'Group_qty'2的值爲'Class B',將1替換爲'Class_A'。

library(data.table) 
setDT(data2)[, NewID:=if(.N>1) shift(ID, type='lead', 
         fill = ID[.N-1]) else ID , by = .(Band)] 
data2[, NewID:= ifelse(Group_qty==2, 'Class B', 
       ifelse(Group_qty==1, 'Class A', NewID))] 
data2 
#  ID Band Group_qty NewID 
# 1: 101 1   4  102 
# 2: 102 1   4  103 
# 3: 103 1   4  104 
# 4: 104 1   4  103 
# 5: 105 2   2 Class B 
# 6: 106 2   2 Class B 
# 7: 107 3   1 Class A 
# 8: 108 4   3  109 
# 9: 109 4   3  110 
#10: 110 4   3  109 

我們可以用類似的方法與dplyr

library(dplyr) 
data2 %>% 
    group_by(Band) %>% 
    mutate(NewID = if(n()==1) ID else dplyr::lead(ID, 
         default= ID[n()-1]), 
      NewID= ifelse(Group_qty==2, 'Class B', 
        ifelse(Group_qty==1, 'Class A', 
         as.character(NewID)))) 
#  ID Band Group_qty NewID 
# (dbl) (dbl)  (dbl) (chr) 
#1 101  1   4  102 
#2 102  1   4  103 
#3 103  1   4  104 
#4 104  1   4  103 
#5 105  2   2 Class B 
#6 106  2   2 Class B 
#7 107  3   1 Class A 
#8 108  4   3  109 
#9 109  4   3  110 
#10 110  4   3  109 
+0

非常感謝。你能解釋一下「轉變」和類型=「領導」和填寫。 – J1975

+0

複雜但「精彩」。因此,通過Group by子句,Group_qty列基本上是多餘的。問題:哪個部分是 - (樂隊)? – J1975

+0

我們很樂意將它與dplyr解決方案進行比較。不是在系統時間方面,而是根據實際的代碼來幫助我學習。提前致謝。 – J1975