首页 > 解决方案 > 使用循环创建多个虚拟变量

问题描述

我正在尝试创建一个循环来创建虚拟变量列。我的专栏mydata$code包含类似"AA1"or的代码"AA2"。我想为每个代码创建一个单独的列,如果代码被命中,则该行的值为 1,否则为 0。我有多个代码,因此我不想全部手动完成。我将如何修复下面的代码以实现此目的?

x <- c("AA1","AA2","AA3","AA4")
for(i in 1:x){
  mydata$code_[i] <- as.integer(str_detect(mydata$code,"i"))
}

当前的

    ID Code 
1 9343  AA1    
2 8333  AA1   
3 6449  AA3  

想要的

    ID Code AA1 AA2 AA3 AA4
1 9343  AA1   1   0   0   0
2 8333  AA1   1   0   0   0
3 6449  AA3   0   0   1   0

标签: rbinarybooleanstringrdummy-variable

解决方案


可以尝试做这样的事情,你循环遍历元素x,然后使用ifelse语句


x <- c("AA1", "AA2", "AA3", "AA4")


db <- data.frame(codes = sample(x, 10, TRUE))

db_new <- cbind(db, Reduce(cbind, lapply(x, function(i) ifelse(db$codes == i, 1, 0))))

如果分贝是:

   codes
1    AA4
2    AA1
3    AA4
4    AA1
5    AA2
6    AA4
7    AA4
8    AA1
9    AA1
10   AA1

然后输出变为:

   codes init V2 V3 V4
1    AA4    0  0  0  1
2    AA1    1  0  0  0
3    AA4    0  0  0  1
4    AA1    1  0  0  0
5    AA2    0  1  0  0
6    AA4    0  0  0  1
7    AA4    0  0  0  1
8    AA1    1  0  0  0
9    AA1    1  0  0  0
10   AA1    1  0  0  0

编辑:

编辑:

看来你的下标是错误的。db$code[j]将采用中列的j第 th 个元素。所以这显然行不通。你可以试试这个:codedb

假设您对所有列使用相同的代码,并且它们在x

x <- c("AA1", "AA2", "AA3", "AA4")

此外,假设您的所有代码列都在您的中data.frame,并且这是您的data.frame.

db <- data.frame(codes_1 = sample(x, 10, TRUE),
                 codes_2 = sample(x, 10, TRUE))

然后我们可以利用这样一个事实,即data.frame工作就像一个列表并且可以通过lapply

db_list <- lapply(seq_along(db), function(i, x) {
  var <- db[[i]]
  var_name <- colnames(db[i])
  db_tmp <- cbind(db[i], Reduce(cbind, lapply(x, function(j) ifelse(var == j, 1, 0))))
  colnames(db_tmp) <- c(var_name, paste(var_name, x, sep = "_"))
  return(db_tmp)
  
}, x)
[[1]]
   codes_1 codes_1_AA1 codes_1_AA2 codes_1_AA3 codes_1_AA4
1      AA1           1           0           0           0
2      AA2           0           1           0           0
3      AA4           0           0           0           1
4      AA3           0           0           1           0
5      AA3           0           0           1           0
6      AA3           0           0           1           0
7      AA3           0           0           1           0
8      AA1           1           0           0           0
9      AA4           0           0           0           1
10     AA4           0           0           0           1

[[2]]
   codes_2 codes_2_AA1 codes_2_AA2 codes_2_AA3 codes_2_AA4
1      AA4           0           0           0           1
2      AA3           0           0           1           0
3      AA3           0           0           1           0
4      AA3           0           0           1           0
5      AA4           0           0           0           1
6      AA1           1           0           0           0
7      AA4           0           0           0           1
8      AA2           0           1           0           0
9      AA2           0           1           0           0
10     AA3           0           0           1           0

这为您提供了一个列表,其中包含您拥有的列数的长度,每个列都有所需的矩阵。如果你想把它全部重新合二为一,你可以这样做:

Reduce(cbind, db_list)


推荐阅读