2016-05-03 92 views
1

我有幾個時間嚴重的變量,我想創建兩個新的虛擬變量。 變量之一:如果其它變量包含一個特定的值,則變量一個等於1.變量 二:如果其它變量包含特定的值連續,那麼可變兩個相等1.創建一個新的變量基於其他變量在r中包含一個特定的值

我的數據看起來像

ID score_2011 score_2012 score_2013 score_2014 score_2015 
1   12   15   96   96   16 
2   12   15   15   15   16 
3   12   96   20   15   16 
4   12   15   18   15   16 
5   12   15   96   15   16 

我想獲得新的變量,如以下

IF score_2011~2015 contain 96 then with_96=1 
IF score_2011~2015 contain continuous 96 then back_to_back_96=1 

我想要的結果看起來像..

ID score_2011 score_2012 score_2013 score_2014 score_2015 with_96 back_to_back_96 
    1   12   15   96   96   16  1    1 
    2   12   15   15   15   16  0    0 
    3   12   96   20   15   16  1    0 
    4   12   15   18   15   16  0    0 
    5   96   15   96   15   16  1    0 

在此先感謝

回答

0

一種辦法是通過行中循環,尋找是否有any值是96(「X1」),做每一行的遊程編碼,檢查是否有是anylengths爲'TRUE'值大於1('x2'),連接,轉置和分配兩個新的列輸出。

df1[c("with_96", "back_to_back_96")] <- t(apply(df1[-1], 1, FUN= function(x) { 
      x1 <- as.integer(any(x==96)) 
      rl <- rle(x==96) 
      x2 <- any(rl$lengths[rl$values]>1) 
      c(x1, x2)})) 
df1 
# ID score_2011 score_2012 score_2013 score_2014 score_2015 with_96 back_to_back_96 
#1 1   12   15   96   96   16  1    1 
#2 2   12   15   15   15   16  0    0 
#3 3   12   96   20   15   16  1    0 
#4 4   12   15   18   15   16  0    0 
#5 5   12   15   96   15   16  1    0 

或者另一種選擇是使用rowSums

df1["with_96"] <- +(!!rowSums(df1[-1]==96)) 
df1["back_to_back_96"] <- rowSums((df1[-c(1, ncol(df1))]==96) + 
       (df1[-c(1,2)]==96)>1) 
+1

謝謝。我從你的答案中學到很多東西。第二個工程。 –

0

,如果你喜歡的話還可以做一些裝飾性與data.table。處理長格式的融化數據集可能會使這些比較中的某些邏輯更簡單一些。

library(data.table) 
setDT(dat) 
melt(dat, id="ID")[, .(with96=any(value==96), b2b96=any(diff(which(value==96))==1)), by=ID] 

# ID with96 b2b96 
#1: 1 TRUE TRUE 
#2: 2 FALSE FALSE 
#3: 3 TRUE FALSE 
#4: 4 FALSE FALSE 
#5: 5 TRUE FALSE 
+0

謝謝。由於數據框中有其他變量,因此如何使用代碼限制到第2列到第5列? –

相關問題