我有一个有列的数据框,
service-id
ids-1-2-3-4-5
ids-1-2-6
ids-5
ids-7-8
与许多其他专栏。我想将数据ids-1-2-3-4-5分成不同的列1,2,3 ... 8,就像一个热编码,列1 2 3 4 5 6 7 8也有1和其余0如果没有。
col.1 col.2 col.3 col.4 col.5 col.6 ..... col.8
1 1 1 1 1 0 ..... 0 for ids-1-2-3-4-5
1 1 0 0 0 1 ...... 0 for ids-1-2-6
我试过tidyverse,但没有用。
使用基本R代码的解决方案。
你的数据
db<-data.frame("service-id"=c("ids-1-2-3-4-5","ids-1-2-6","ids-5","ids-7-8"))
确定列数
ncol<-max(suppressWarnings(as.numeric(unlist(strsplit(as.character(db$service.id),"-")))),na.rm = T)
提取数字ID列表
number_list<-strsplit(as.character(db$service.id),"-")
number_list<-suppressWarnings(lapply(number_list,as.numeric))
number_list <- lapply(number_list, function(x) x[!is.na(x)])
创建输出数据框
f<-function(x,ncol)
{
return(as.numeric(seq(1:ncol) %in% x))
}
out<-t(data.frame(lapply(number_list, f, ncol=ncol)))
colnames(out)<-paste0("col.",seq(1:ncol))
rownames(out)<-NULL
你的输出
out
col.1 col.2 col.3 col.4 col.5 col.6 col.7 col.8
[1,] 1 1 1 1 1 0 0 0
[2,] 1 1 0 0 0 1 0 0
[3,] 0 0 0 0 1 0 0 0
[4,] 0 0 0 0 0 0 1 1
如果我们需要tidyverse
选项,这是一种方法
library(tidyverse)
df1 %>%
rownames_to_column('rn') %>%
extract(service.id, into = c('id', 'col'), "^([^-]+)-(.*)") %>%
separate_rows(col) %>%
mutate(n = 1, col = paste0("col.", col)) %>%
spread(col, n, fill = 0) %>%
select(-rn, -id)
# col.1 col.2 col.3 col.4 col.5 col.6 col.7 col.8
#1 1 1 1 1 1 0 0 0
#2 1 1 0 0 0 1 0 0
#3 0 0 0 0 1 0 0 0
#4 0 0 0 0 0 0 1 1
df1 <- structure(list(service.id = c("ids-1-2-3-4-5", "ids-1-2-6", "ids-5",
"ids-7-8")), .Names = "service.id", class = "data.frame", row.names = c(NA,
-4L))