2012-02-03 44 views
4

假設我有一個持續幾個時段的變量。 就像我擁有一個Ipod的年數一樣。 所以我從2001年到2004年的Ipod第一代,然後在2005年,我得到了Ipod 2等等。所以,我的數據框看起來像:虛擬系列中的第一個新元素

2001 Ipod1 
    2002 Ipod1 
    2003 Ipod1 
    2004 Ipod1 
    2005 Ipod2 
    2006 Ipod2 
    2007 Ipod2 
    2008 Ipod2 
    2009 Ipod3 
    2010 Ipod3 

我要的是創建一個虛擬期間時,一個新的變量到達,所以我會得到:

Year Var Dummy 
    2001 Ipod1 1 
    2002 Ipod1 0 
    2003 Ipod1 0 
    2004 Ipod1 0 
    2005 Ipod2 1 
    2006 Ipod2 0 
    2007 Ipod2 0 
    2008 Ipod2 0 
    2009 Ipod3 1 
    2010 Ipod3 0 

到目前爲止,我已經能夠做到這個:

df = structure(list(Year = 2001:2010, Var = structure(c(1L, 1L, 1L, 
1L, 2L, 2L, 2L, 2L, 3L, 3L), .Label = c("Ipod1", "Ipod2", "Ipod3" 
), class = "factor")), .Names = c("Year", "Var"), class = "data.frame", row.names = c(NA, 
-10L)) 

df$number.in.group = unlist(lapply(table(df$Var),seq.int)) 
df$dummy = ifelse(df$number.in.group == 1,1,0) 
df$dummy[1]=0 

其實我想讓虛擬元素的第一個元素爲零。

我的問題是:有沒有辦法以更好的方式做到這一點?

感謝

+0

該指標變量應該是一個邏輯值,而不是一個號碼,因爲它記錄一個事件是否發生;它不算數。 – 2012-02-03 11:11:59

+1

'lm'(和類似的模型)會將一個邏輯值轉換成一個'factor'。也就是說,具有兩種狀態的分類變量。無論是因素還是數字,係數都是相同的。 – 2012-02-03 13:40:48

回答

9

如何:

df$Dummy <- as.numeric(!duplicated(df$Var)) 

# Or, if you want the first element to be 0, 
df$Dummy <- c(0, as.numeric(!duplicated(df$Var))[-1]) 
+0

非常好。再次,一個有用的'基本'功能顯示出我從未學過。 :-) – 2012-02-03 14:47:24

+0

@CarlWitthoft - 我知道你的意思。就在那一天,我發現了'rowsum()',並且想'這些年你都藏在哪兒了,然後就有'nextn()'這樣的函數,我也剛剛發現它,對此我認爲,「那個人究竟是如何將它變成一個基本的R包?」(儘管我想這肯定是有原因的)! – 2012-02-03 18:02:50

5

我相信這給期望的結果:

> df$Dummy <- c(0, diff(as.numeric(df$Var))) 
> df 
    Year Var Dummy 
1 2001 Ipod1  0 
2 2002 Ipod1  0 
3 2003 Ipod1  0 
4 2004 Ipod1  0 
5 2005 Ipod2  1 
6 2006 Ipod2  0 
7 2007 Ipod2  0 
8 2008 Ipod2  0 
9 2009 Ipod3  1 
10 2010 Ipod3  0 

這工作,因爲無功是因此使用as.numeric作品的一個因素。

2

rle函數在這種情況下非常有用。它發現矢量中同一項目的連續運行。

rle_result = rle(as.character(df$Var)) 
rle_result 
Run Length Encoding 
    lengths: int [1:3] 4 4 2 
    values : chr [1:3] "Ipod1" "Ipod2" "Ipod3" 

構建新的變量:

df$new = 0 
change_ids = 1 + cumsum(rle_result$lengths) 
df$new[change_ids[-length(change_ids)]] <- 1 
df 
    Year Var new 
1 2001 Ipod1 0 
2 2002 Ipod1 0 
3 2003 Ipod1 0 
4 2004 Ipod1 0 
5 2005 Ipod2 1 
6 2006 Ipod2 0 
7 2007 Ipod2 0 
8 2008 Ipod2 0 
9 2009 Ipod3 1 
10 2010 Ipod3 0 

這正是您要尋找的,我認爲。

2

(1)該問題詢問Dummy列,但問題中的示例答案也生成number.in.group列,因此我不確定是否需要number.in.group列;然而,在下面我們假設它是需要的。需要注意的是0到的Dummy第一元件的分配具有列轉換爲數字的效果:

within(df, { 
    number.in.group <- ave(Year, Var, FUN = seq_along) 
    Dummy <- number.in.group == 1 
    Dummy[1] <- 0 
}) 

(2a)中如果不需要number.in.groupVar組是連續的如實施例則

df$Dummy <- !duplicated(df$Var) 
df$Dummy[1] <- 0 
儘管這需要一個額外的聲明

:除了我認爲這將是稍微清晰的,如果它被寫成這樣已經出現duplicated的解決方案將是可取的。

(2b)的同時,我們也可能更喜歡以非破壞性的形式:

within(df, { 
    Dummy <- !duplicated(Var) 
    Dummy[1] <- 0 
}) 
相關問題