簡體   English   中英

如何在R中創建“最大”虛擬變量?

[英]How to create a “max” dummy variables in R?

我想創建一個“ max”和一個條件偽變量。 假設我有一個看起來像這樣的數據集:

   Subject  Year    X   Ydummy
       A    1990    0   0
       A    1991    1   0
       A    1992    2   0
       A    1993    0   0
       A    1995    1   0
       A    1996    2   0
       A    1997    3   0
       B    1990    0   0
       B    1991    0   0
       B    1992    0   0
       B    1993    1   0
       B    1995    2   0
       B    1996    3   0
       B    1997    3   0
       C    1990    1   0
       C    1991    2   0
       C    1992    3   0
       C    1993    3   0
       C    1995    3   0
       C    1996    3   0
       C    1997    3   0
       C    1998    3   1
       D    1990    0   0
       D    1991    0   0
       D    1992    1   0
       D    1993    2   0
       D    1995    3   0
       D    1996    3   0
       D    1997    4   0

X變量是一個累積變量(衡量每個Subject-Year)。

(1)我想創建一組“最大”的虛擬變量:可以指示X是否達到最大值1,2,3的虛擬變量,依此類推。 為簡化起見,假設我對創建變量“ Xmax3”感興趣。 “ Xmax3”指示X的最大值是否等於3(對於每個學科年)。 如果最大X值為3,則“ Xmax3”為1,否則為0。 使事情變得復雜的是,我希望僅當X首次變為3時才將其設為1。 或第一次達到最大值。 請參見下面的示例。

我嘗試使用以下方法創建此變量:

data$Xmax3 <- ave(data$X, data$Subject, FUN = function(x) if (max(x) == 3) 1 else 0) 

但這並不能控制0,因為我希望X變成3時只能為1。

(2)基於“ Xmax3”,我想生成一個條件偽變量“ ” Xmax3_noY“ 。該變量應指示在X達到最大值3后的5年后Y是否為1。年,則“ “ Xmax3_noY”應該為0。

因此,如果您看下面的示例,您會發現對於C – 1992“ Xmax3”為1。 但是“ Xmax3_noY”為0,因為C – 1998的Y為1。如果1999年(6年后)的Y為1,則“ Xmax3_noY”的有效性也將為 1。

示例(理想的結果):

Subject     Year    X   Ydummy  Xmax3   Xmax3_noY
       A    1990    0      0      0        0
       A    1991    1      0      0        0
       A    1992    2      0      0        0
       A    1993    0      0      0        0
       A    1995    1      0      0        0
       A    1996    2      0      0        0
       A    1997    3      0      1        1
       B    1990    0      0      0        0
       B    1991    0      0      0        0
       B    1992    0      0      0        0
       B    1993    1      0      0        0
       B    1995    2      0      0        0
       B    1996    3      0      1        1
       B    1997    3      0      0        0
       C    1990    1      0      0        0
       C    1991    2      0      0        0
       C    1992    3      0      1        0
       C    1993    3      0      0        0
       C    1995    3      0      0        0
       C    1996    3      0      0        0
       C    1997    3      0      0        0
       C    1998    3      1      0        0
       D    1990    0      0      0        0
       D    1991    0      0      0        0
       D    1992    1      0      0        0
       D    1993    2      0      0        0
       D    1995    3      0      0        0
       D    1996    3      0      0        0
       D    1997    4      0      0        0

您將如何創建這兩個變量? 我非常感謝“教學法”(如果可能)的任何建議,允許我嘗試使用這些變量的不同版本。

可重現的樣品:

> dput(data)
structure(list(Subject = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 
1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
4L, 4L, 4L, 4L, 4L, 4L, 4L), .Label = c("A", "B", "C", "D"), class = "factor"), 
    Year = c(1990L, 1991L, 1992L, 1993L, 1995L, 1996L, 1997L, 
    1990L, 1991L, 1992L, 1993L, 1995L, 1996L, 1997L, 1990L, 1991L, 
    1992L, 1993L, 1995L, 1996L, 1997L, 1998L, 1990L, 1991L, 1992L, 
    1993L, 1995L, 1996L, 1997L), X = c(0L, 1L, 2L, 0L, 1L, 2L, 
    3L, 0L, 0L, 0L, 1L, 2L, 3L, 3L, 1L, 2L, 3L, 3L, 3L, 3L, 3L, 
    3L, 0L, 0L, 1L, 2L, 3L, 3L, 4L), Ydummy = c(0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L)), .Names = c("Subject", 
"Year", "X", "Ydummy"), class = "data.frame", row.names = c(NA, 
-29L))

編輯(與史蒂芬·博普雷交談后):

Xmax3變量應指示何時達到X的第一個最大值,即在這種情況下X何時達到3。

對於Xmax3_noY變量,條件是:如果在X達到最大(也是第一個)值3之后的接下來的5年中,數據集中的Y == 1,則Xmax3_noY ==0。換句話說, Xmax_noY == 1如果在(Year +5)內沒有Ydummy == 1

另外,最好將Xmax3_noY變量的條件設置為不僅在5年之后,而且在5年之前 換言之: 本Xmax_noY == 1,如果它不是Ydummy == 1內的(年-5):(年份+ 5)

library(data.table)
dt = as.data.table(data) # or setDT to convert in place

dt[, Xmax3 := 0][X == 3, Xmax3 := c(1, rep(0, .N-1)), by = Subject][
                       , Xmax3 := if (max(X) > 3) 0, by = Subject]
dt[, Xmax3_noY := 0][X == 3,
                     Xmax3_noY := if(all(Ydummy[Year <= Year[1] + 6] == 0)) Xmax3 else 0,
                     by = Subject]
dt
#    Subject Year X Ydummy Xmax3 Xmax3_noY
# 1:       A 1990 0      0     0         0
# 2:       A 1991 1      0     0         0
# 3:       A 1992 2      0     0         0
# 4:       A 1993 0      0     0         0
# 5:       A 1995 1      0     0         0
# 6:       A 1996 2      0     0         0
# 7:       A 1997 3      0     1         1
# 8:       B 1990 0      0     0         0
# 9:       B 1991 0      0     0         0
#10:       B 1992 0      0     0         0
#11:       B 1993 1      0     0         0
#12:       B 1995 2      0     0         0
#13:       B 1996 3      0     1         1
#14:       B 1997 3      0     0         0
#15:       C 1990 1      0     0         0
#16:       C 1991 2      0     0         0
#17:       C 1992 3      0     1         0
#18:       C 1993 3      0     0         0
#19:       C 1995 3      0     0         0
#20:       C 1996 3      0     0         0
#21:       C 1997 3      0     0         0
#22:       C 1998 3      1     0         0
#23:       D 1990 0      0     0         0
#24:       D 1991 0      0     0         0
#25:       D 1992 1      0     0         0
#26:       D 1993 2      0     0         0
#27:       D 1995 3      0     0         0
#28:       D 1996 3      0     0         0
#29:       D 1997 4      0     0         0
#    Subject Year X Ydummy Xmax3 Xmax3_noY

這是一個解決方案,它將生成從1到4的Xmax_nXmax_n_noY列(8個新列)並滿足以下條件:

  • Xmax_n列中每個Subject內的X的第一個最大值僅表示1
  • 與表示0的值Xmax_n_noY對於每列Xmax_n值,如果有一個Ydummy的值1Subject組之前或之后的范圍內的5年之內Year ,否則, 1

library(dplyr)
library(tidyr)

data %>%
  group_by(Subject, X) %>%
  mutate(maxt   = ifelse(X != 0 & row_number(X) == 1, paste0("Xmax", X), NA),
         maxnoy = ifelse(!is.na(maxt), paste0("Xmax", X, "_noY"), NA),
         val    = ifelse(!is.na(maxt), 1, 0)) %>%
  group_by(Subject) %>%
  mutate(Y2  = ifelse(!is.na(maxnoy) & any(Ydummy == 1), Year[Ydummy == 1], NA),
         L   = ifelse(!is.na(maxnoy) & !is.na(Y2), Y2 %in% list((Year-5):(Year+5)), 1)) %>%
  spread(maxnoy, L, fill = 0) %>%
  spread(maxt, val, fill = 0) 

在第一部分中,我們group_by() SubjectX生成重要性為maxtvalmaxnoy三個新列

data %>%
  group_by(Subject, X) %>%
  mutate(maxt   = ifelse(X != 0 & row_number(X) == 1, paste0("Xmax", X), NA),
         maxnoy = ifelse(!is.na(maxt), paste0("Xmax", X, "_noY"), NA),
         val    = ifelse(!is.na(maxt), 1, 0)) %>%

然后,我們產生重要性的第四列L將於0對於每個Xmax_n如果有一個Ydummy的值1的在Subject組的范圍內的先前或后的5年內Year ,否則, 1

 group_by(Subject) %>%
  mutate(Y2  = ifelse(!is.na(maxnoy) & any(Ydummy == 1), Year[Ydummy == 1], NA),
         L   = ifelse(!is.na(maxnoy) & !is.na(Y2), Y2 %in% list((Year-5):(Year+5)), 1)) %>%

然后,我們spread() maxtvalmaxnoyLspread() ,以實現所需的輸出格式。

  spread(maxnoy, L, fill = 0) %>%
  spread(maxt, val, fill = 0) 

如果數據不是很大,則可以使用循環來解決問題。 通常認為這很糟糕,但是您可以輕松地將以下循環的命令轉換為可以通過apply執行的功能(請參見?apply

因此,讓我們說data_size是數據的長度,即data_size <- dim(data)[1]那么您可以分兩步計算Xmax3列。 首先是以下循環:

data$Xmax3 <- 0
for (t in 1:data_size) {
  if (data$X[t] == 3) {
    data$Xmax3[t] <- 1
  }
}

如果您願意使用dplyr,也可以更優雅地表達它:

data <- dplyr::mutate(data,Xmax3 = ifelse ((X == 3), 1 , 0)) 

然后,在第二步中,我們希望消除跟隨1的所有1。同樣,有多種方法可以實現這一點。 一種可能性是使用diff(x)函數(請參閱?diff )。 它返回x值之間的差。 例如: diff(c(1,2,5,6,1))將返回'1 3 1 -5'。 請注意,返回的向量要比提供的向量短一,因為已取得了差異。 接下來的部分比較笨拙,因為Xmax3_diff我們需要將Xmax3行的第一個值連接回去並刪除所有低於0的值:

Xmax3_diff <- diff(data$Xmax3)
data$Xmax3 <- pmax( c(data$Xmax3[1],Xmax3_diff) , 0)

完成此操作后,可以再次使用循環獲取Xmax3_noY列。 這次我們關心的是數據的最后一行!

buffer <- 5 # 5 because we want to check 5 years a head of the current time step
data$Xmax3_noY <- 0
for (t in 1:(data_size-buffer)) {
  # check if the the next 5 years of the Ydummy column are all 0
  test_for_followup_years <- any(data$Ydummy[t:(t+buffer)] == 0) 
  # If hte conditions we want are met, then set max3_noY to 1
  if ( (data$Xmax3[t] == 1) & test_for_followup_years ) {
    data$Xmax3_noY[t] <- 1
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM