R 从因子级别的子字符串创建虚拟变量 目标

R 从因子级别的子字符串创建虚拟变量 目标,r,string,R,String,使用包含NA或由空格分隔的整数序列的因子变量,我试图创建一系列伪变量(var1,var2,…,vari),如果字符串包含整数I(而不仅仅是字符I),则取1;如果字符串包含NA,则取NA;否则取0 问题 我有点卡住了,因为我尝试使用grep()在字符串中搜索定义每个整数的字符,但这会返回行号,而不是布尔向量。此外,搜索“7”将返回“77”、“97”等,而不仅仅是“7” 例子 因此,在下面的最小工作数据中,我希望伪变量var0,var1,var2,var3,var33,var999在data==NA

使用包含NA或由空格分隔的整数序列的因子变量,我试图创建一系列伪变量(var1,var2,…,vari),如果字符串包含整数I(而不仅仅是字符I),则取1;如果字符串包含NA,则取NA;否则取0

问题 我有点卡住了,因为我尝试使用grep()在字符串中搜索定义每个整数的字符,但这会返回行号,而不是布尔向量。此外,搜索“7”将返回“77”、“97”等,而不仅仅是“7”

例子 因此,在下面的最小工作数据中,我希望伪变量var0,var1,var2,var3,var33,var999在data==NA时取NA,在data==x时取1,否则取0。我已经开始尝试解决这个问题,但没有成功。由于我的实际数据非常大,我正在寻找一种通用方法

# Create data
data <- c("0 1 2", "0 2 3", "999", "33", "33 0 3", NA, "33 0 3") %>% factor()

# Attempt to complete task (doesn't work)
data <- cbind(data,
            setNames(
              data.frame(
                sapply(
                  data,
                  function(i) ifelse(is.na(data),
                                            NA,
                                            ifelse(# do something to create variables w/ value 1,0)))),
              paste0("var",
                    valuenumber))

您需要使用
grepl
返回
T
F
而不是
grep
返回匹配的值或匹配的位置,而且由于您使用的是字符串,因此最好从字符开始,而不是从因子开始,下面是一些如何操作的开始。将变量名称重命名为
Vari
应提供所需的输出:

data <- c("0 1 2", "0 2 3", "999", "33", "33 0 3", NA, "33 0 3")

valueNumbers <- na.omit(unique(unlist(strsplit(data, " "))))
newData <- sapply(valueNumbers, function(i) replace(as.integer(
                  grepl(paste("\\b", i, "\\b", sep = ""), data)), is.na(data), NA))

newData

      0  1  2  3 999 33
[1,]  1  1  1  0   0  0
[2,]  1  0  1  1   0  0
[3,]  0  0  0  0   1  0
[4,]  0  0  0  0   0  1
[5,]  1  0  0  1   0  1
[6,] NA NA NA NA  NA NA
[7,]  1  0  0  1   0  1

数据使用strsplit和match:

# data
data <- factor(c("0 1 2", "0 2 3", "999", "33", "33 0 3", NA, "33 0 3"))

# make list
dList <- sapply(as.character(data), strsplit, split = " ")
# unique items
items <- sort(unique(unlist(dList)))

# result
res <- data.frame(!is.na(t(sapply(dList, match, x = items)))) * 1
colnames(res) <- paste0("var", items)

# make no matches NA
res[rowSums(res) == 0,] <- NA


cbind(data, res)
#       data var0 var1 var2 var3 var33 var999
# 1    0 1 2    1    1    1    0     0      0
# 2    0 2 3    1    0    1    1     0      0
# 3      999    0    0    0    0     0      1
# 4       33    0    0    0    0     1      0
# 5   33 0 3    1    0    0    1     1      0
# 6     <NA>   NA   NA   NA   NA    NA     NA
# 7   33 0 3    1    0    0    1     1      0
#数据

您可以粘贴所需的输出数据吗?在我看来,所有变量的值都是1,因为所有的i都在数据中?上面提供了一个所需输出的示例。可能有点不对劲,因为我需要手动键入值。另外还提供了关于“33”和“3”的困难之一的评论。@user3614648为什么不?通过提供的示例数据,此代码可以正常工作。你的意思是因为这是一个因素吗?看我的编辑。你编辑,现在它的作品-需要投到字符。很好的使用strsplit。加一
# data
data <- factor(c("0 1 2", "0 2 3", "999", "33", "33 0 3", NA, "33 0 3"))

# make list
dList <- sapply(as.character(data), strsplit, split = " ")
# unique items
items <- sort(unique(unlist(dList)))

# result
res <- data.frame(!is.na(t(sapply(dList, match, x = items)))) * 1
colnames(res) <- paste0("var", items)

# make no matches NA
res[rowSums(res) == 0,] <- NA


cbind(data, res)
#       data var0 var1 var2 var3 var33 var999
# 1    0 1 2    1    1    1    0     0      0
# 2    0 2 3    1    0    1    1     0      0
# 3      999    0    0    0    0     0      1
# 4       33    0    0    0    0     1      0
# 5   33 0 3    1    0    0    1     1      0
# 6     <NA>   NA   NA   NA   NA    NA     NA
# 7   33 0 3    1    0    0    1     1      0