创建虚拟变量,条件是要进行面板观察的匹配值

时间:2019-12-06 13:58:42

标签: r data.table

我有一个data.table,它具有一个名为varB的虚拟变量。我想将varB转换为另一个变量,例如new_dummy_var

library(data.table)
DT <- fread("
ID varA varB varC year
1  3    1    6    1
1  2    1    7    2
2  2    0    7    1
2  1    0    8    2
3  5    1    9    3
3  4    1    4    4
4  2    0    3    1
4  5    0    3    2
5  3    1    9    1
5  2    1    9    2
6  2    0    5    1
6  1    0    6    2
7  5    1    6    1
7  4    0    3    2
8  2    0    3    1
8  5    1    4    2",
header = TRUE)

对于所有ID,我希望new_var_dummy0的第一项中是ID,在1的第二项中是ID对于整个varB对,1ID。对于其他所有变量,虚拟变量均为零。

所需的输出:

DT <- fread("
ID varA varB varC year new_dummy_var
1  3    1    6    1    0
1  2    1    7    2    1
2  2    0    7    1    0
2  1    0    8    2    0
3  5    1    9    3    0
3  4    1    4    4    1
4  2    0    3    1    0
4  5    0    3    2    0
5  3    1    9    1    0
5  2    1    9    2    1
6  2    0    5    1    0
6  1    0    6    2    0
7  5    1    6    1    0
7  4    0    3    2    0
8  2    0    3    1    0
8  5    0    4    2    0",
header = TRUE)

作为示例:varB在两个年份中都是1的{​​{1}},因此对于新的假人来说,第一年是ID==1,{{1} }。与0

类似

对于1的7和8,并不是两行的ID==3都是ID,所以它们变为零。

我正在考虑做类似的事情:

varB

但这会发出警告:

1

然后我尝试:

pdataframe <- setDT(pdataframe)[sum(varB, by=ID)==2, new_dummy_var:=sample(c("0","1"),2)  ,by=c("ID","varC")]

导致相同的错误。

我应该怎么做?

2 个答案:

答案 0 :(得分:1)

您可以使用varBwhich中获得第二次出现1的索引,并将该索引变成1,然后将每个ID的索引全部归零。

library(data.table)
DT[, new_dummy_var := +(seq_along(varB) %in% which(varB == 1)[2]), ID]

#    ID varA varB varC year new_dummy_var
# 1:  1    3    1    6    1             0
# 2:  1    2    1    7    2             1
# 3:  2    2    0    7    1             0
# 4:  2    1    0    8    2             0
# 5:  3    5    1    9    3             0
# 6:  3    4    1    4    4             1
# 7:  4    2    0    3    1             0
# 8:  4    5    0    3    2             0
# 9:  5    3    1    9    1             0
#10:  5    2    1    9    2             1
#11:  6    2    0    5    1             0
#12:  6    1    0    6    2             0
#13:  7    5    1    6    1             0
#14:  7    4    0    3    2             0
#15:  8    2    0    3    1             0
#16:  8    5    1    4    2             0

在R的基础上可以做到

DT$new_dummy_var <- with(DT, +ave(varB == 1, ID, 
                            FUN = function(x) seq_along(x) %in% which(x)[2]))

dplyr

library(dplyr)

DT %>%
  group_by(ID) %>%
  mutate(new_dummy_var = +(row_number() %in% which(varB == 1)[2]))

答案 1 :(得分:1)

我们可以使用

library(data.table)
DT[, new_dummy_var := as.integer(seq_len(.N) %in% which(varB == 1)[2]), ID]

或使用.I

DT[, new_dummy_var := 0]
DT[na.omit(DT[, .I[varB == 1][2], ID]$V1), new_dummy_var := 1]
DT
#    ID varA varB varC year new_dummy_var
# 1:  1    3    1    6    1             0
# 2:  1    2    1    7    2             1
# 3:  2    2    0    7    1             0
# 4:  2    1    0    8    2             0
# 5:  3    5    1    9    3             0
# 6:  3    4    1    4    4             1
# 7:  4    2    0    3    1             0
# 8:  4    5    0    3    2             0
# 9:  5    3    1    9    1             0
#10:  5    2    1    9    2             1
#11:  6    2    0    5    1             0
#12:  6    1    0    6    2             0
#13:  7    5    1    6    1             0
#14:  7    4    0    3    2             0
#15:  8    2    0    3    1             0
#16:  8    5    1    4    2             0