[英]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_n
和Xmax_n_noY
列(8個新列)並滿足以下條件:
Xmax_n
列中每個Subject
內的X
的第一個最大值僅表示1
0
的值Xmax_n_noY
對於每列Xmax_n
值,如果有一個Ydummy
的值1
中Subject
組之前或之后的范圍內的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()
Subject
和X
生成重要性為maxt
, val
和maxnoy
三個新列
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()
maxt
& val
和maxnoy
& L
對spread()
,以實現所需的輸出格式。
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.