![](/img/trans.png)
[英]Similar but different to: Split unique values into separate columns for multiple columns
[英]Split unique values into separate columns for multiple columns
我的數據的每個列都將重新縮放並放入0到100的bin中。bin列將用作模型的特征。 為了分別測試每個bin,我想將每個bin列分為每個值的單獨列。 新列將保持為0或1,具體取決於單元格中的值是否與列的bin匹配。 從這樣的事情:
row values
1 10
2 20
3 30
4 40
5 10
6 30
7 40
對此:
row values_10 values_20 values_30 values_40
1 1 0 0 0
2 0 1 0 0
3 0 0 1 0
4 0 0 0 1
5 1 0 0 0
6 0 0 1 0
7 0 0 0 1
這種蠻力方法可以完成工作,但是必須有更好的(非循環)方法:
values <- c( 10,20,30,40,10,30,40)
dat <- data.frame(values)
columnNames <- unique(dat$values)
for( n in 1:length(columnNames) )
{
dat[as.character(columnNames[n])] <- 0
}
columnNames2 <- colnames(dat)
for( c in 2:ncol(dat))
{
hdr <- columnNames2[c]
for( r in 1:nrow(dat))
{
if( dat$values[r]==as.integer(hdr) )
dat[r,c]=1
}
}
非常感謝!!
編輯
這些都是很好的答案,謝謝大家。 最終對象(無論是矩陣,表還是data.table)將僅包含單獨的bin列(不包含源列)。 以下解決方案如何用於2000多個源列?
編輯2
根據對我的后續問題的答案,以下是針對將來遇到此問題的任何人的每種方法的實現。
# read in some data with multiple columns
df_in <- read.table(text="row val1 val2
1 10 100
2 20 200
3 30 300
4 40 400
5 10 100
6 30 300
7 40 400", header=TRUE, stringsAsFactors=FALSE)
# @Zelazny7 's method using a matrix
df_in$row <- NULL
col_names <- names(df_in)
for( c in 1:length(col_names)){
uniq <- unlist(unique(df_in[col_names[c]]))
m <- matrix(0, nrow(df_in), length(uniq),
dimnames = list(NULL, paste0(col_names[c], "_", uniq)))
for (i in seq_along(df_in[[col_names[c]]])) {
k <- match(df_in[[col_names[c]]][i], uniq, 0)
m[i,k] <- 1
}
if( c==1 )
df_out <- m
else
df_out <- cbind(df_out,m)
}
# @P Lapointe 's method using 'table'
col_names <- names(df_in)
for( c in 2:length(col_names)){
m <- table(df_in$row,df_in[[col_names[c]]])
uniq <- unlist(unique(df_in[col_names[c]]))
newNames <- toString(paste0(col_names[c],'_',uniq))
if( c==2 ){
df_out <- m
hdrs <- newNames
}
else{
df_out <- cbind(df_out,m)
hdrs <- paste(hdrs,newNames,sep=", ")
}
}
colnames(df_out) <- unlist(strsplit(hdrs, split=", "))
# @bdemarest 's method using 'data.table'
# read in data first
library(data.table)
df_in = fread("row val1 val2
1 10 100
2 20 200
3 30 300
4 40 400
5 10 100
6 30 300
7 40 400")
df_in$count = 1L
col_names <- names(df_in)
for( c in 2:length(col_names)-1){
m = dcast(df_in, paste( 'row', '~', col_names[c]), value.var="count", fill=0L)
uniq <- unlist(unique(df_in[,get(col_names[c])]))
newNames <- toString(paste0(col_names[c],'_',uniq))
m$row <- NULL
if( c==2 ){
df_out <- m
hdrs <- newNames
}
else if( c>2 ){
df_out <- cbind(df_out,m)
hdrs <- paste(hdrs,newNames,sep=", ")
}
}
colnames(df_out) <- unlist(strsplit(hdrs, split=", "))
所有答案都是適當且可用的,因此最好的答案是最快的初始響應。 再次感謝你的幫助!!
我經常這樣做。 這是我用來創建假人的方法。 非常快。
## reading in your example data
df <- read.table(file = "clipboard", header=TRUE)
df$row <- NULL
uniq <- unique(df$values)
m <- matrix(0, nrow(df), length(uniq), dimnames = list(NULL, paste0("column_", uniq)))
for (i in seq_along(df$values)) {
k <- match(df$values[i], uniq, 0)
m[i,k] <- 1
}
結果:
> m
column_10 column_20 column_30 column_40
[1,] 1 0 0 0
[2,] 0 1 0 0
[3,] 0 0 1 0
[4,] 0 0 0 1
[5,] 1 0 0 0
[6,] 0 0 1 0
[7,] 0 0 0 1
通過使用矩陣索引矩陣來避免循環的另一個變體:
m[cbind(seq.int(nrow(m)), match(df$values, uniq))] <- 1
使用table
:
df1 <- read.table(text="row values
1 10
2 20
3 30
4 40
5 10
6 30
7 40", header=TRUE, stringsAsFactors=FALSE)
table(df1)
values
row 10 20 30 40
1 1 0 0 0
2 0 1 0 0
3 0 0 1 0
4 0 0 0 1
5 1 0 0 0
6 0 0 1 0
7 0 0 0 1
您可以像這樣對table
索引:
table(df1)[5,1]
[1] 1
編輯要回答您的其他請求,您可以像這樣創建新的列名:
tbl <-table(df1)
out<-as.data.frame.matrix(tbl) #to transform into a data.frame
colnames(out) <-make.names(colnames(out)) #to make new column names
out
X10 X20 X30 X40
1 1 0 0 0
2 0 1 0 0
3 0 0 1 0
4 0 0 0 1
5 1 0 0 0
6 0 0 1 0
7 0 0 0 1
這是一個data.table
解決方案。 我首先添加一個count
列,然后使用dcast()
其dcast()
為寬格式。 順便說一下,這足夠快以用於具有1000萬或更多行的數據。
library(data.table)
tab = fread("row values
1 10
2 20
3 30
4 40
5 10
6 30
7 40")
tab$count = 1L
res = dcast(tab, row ~ values, value.var="count", fill=0L)
res
# row 10 20 30 40
# 1: 1 1 0 0 0
# 2: 2 0 1 0 0
# 3: 3 0 0 1 0
# 4: 4 0 0 0 1
# 5: 5 1 0 0 0
# 6: 6 0 0 1 0
# 7: 7 0 0 0 1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.