Xin chào các bạn, trong quá trình phân tích dữ liệu, mình cần chuyển đổi tất cả các giá trị trong 1 cột thành nhiều cột. Đồng thời điền vào giá trị là 1 hoặc 0 tương ứng. Để thực hiện được yêu cầu này mình đã tổng hợp được một số cách để chuyển đổi với phần mềm R như sau đây.
Mình có dữ liệu ví dụ như data.frame df. Trong đó cột flower_color có 4 giá trị là: do, xanh, vang, trang. Yêu cầu tách 4 giá trị này thành 4 cột tương ứng
df
id flower_color
1 1 do
2 2 xanh
3 3 vang
4 4 trang
model.matrix đã được load sẵn trong Rdf1=model.matrix(~id+flower_color-1, df)
df1=as.data.frame(df1)
df1
id flower_colordo flower_colortrang flower_colorvang flower_colorxanh
1 1 1 0 0 0
2 2 0 0 0 1
3 3 0 0 1 0
4 4 0 1 0 0
dummy.data.frame và dummy trong package dummieslibrary(dummies)
#dummy(df$flower_color)
dummy.data.frame(df, sep="_")
id flower_color_do flower_color_trang flower_color_vang
1 1 1 0 0
2 2 0 0 0
3 3 0 0 1
4 4 0 1 0
flower_color_xanh
1 0
2 1
3 0
4 0
dummy.code trong package psychlibrary(psych)
df1=cbind(df,dummy.code(df$flower_color))
df1
id flower_color do trang vang xanh
1 1 do 1 0 0 0
2 2 xanh 0 0 0 1
3 3 vang 0 0 1 0
4 4 trang 0 1 0 0
dcast trong package reshape2library(reshape2)
dcast(df,id~ flower_color, length)
id do trang vang xanh
1 1 1 0 0 0
2 2 0 0 0 1
3 3 0 0 1 0
4 4 0 1 0 0
acm.disjonctif trong package ade4library(ade4)
acm.disjonctif(df[2])
flower_color.do flower_color.trang flower_color.vang flower_color.xanh
1 1 0 0 0
2 0 0 0 1
3 0 0 1 0
4 0 1 0 0
forfor(level in unique(df$flower_color)){
df[paste("dummy", level, sep = "_")] <- ifelse(df$flower_color == level, 1, 0)
}
df
id flower_color dummy_do dummy_xanh dummy_vang dummy_trang
1 1 do 1 0 0 0
2 2 xanh 0 1 0 0
3 3 vang 0 0 1 0
4 4 trang 0 0 0 1
Như vậy có rất nhiều cách để thực hiện việc này một cách dễ dàng đối với R. Tuy nhiên trường hợp của mình phức tạp hơn ví dụ trên. Trường hợp của mình có nhiều giá trị trong cùng một ô. Ví dụ như data sau: id4 có 3 giá trị, id5 có 2 giá trị
flower_color=c("do","xanh","vang","do;trang;xanh", "xanh;vang")
id=c(1,2,3,4,5)
df=data.frame(id,flower_color)
df
id flower_color
1 1 do
2 2 xanh
3 3 vang
4 4 do;trang;xanh
5 5 xanh;vang
Nếu mình sử dụng cách ở trên thì R sẽ hiểu 3 giá trị do;trang;xanh là 1 giá trị. VD:
dcast(df,id~ flower_color, length)
id do do;trang;xanh vang xanh xanh;vang
1 1 1 0 0 0 0
2 2 0 0 0 1 0
3 3 0 0 1 0 0
4 4 0 1 0 0 0
5 5 0 0 0 0 1
Hiện tại mình chưa tìm được lệnh nào nên tạm thời đã tự viết một function: b.dummy() để thực hiện cho trường hợp này của mình. script của function như sau:
b.dummy=function(df, col,sep=';'){
column=df[,col]
#Ham lay gia tri trong cot
b.get.value=function(list,sep=";")
{
a=paste(list,collapse = sep)
b=strsplit(a,sep)
c=unique(b[[1]])
return(c)
}
#Tao mang chua cac gia tri
arr=b.get.value(column,sep)
#thuc hien vong lap for
for(level in unique(arr)){
i=1
for (values in column)
{
values=as.character(values)
value_list=strsplit(values,sep)
for (value in value_list[[1]])
{
if(value==level){
df[i,paste("dummy", level, sep = "_")] =1
break
}
else
{
df[i,paste("dummy", level, sep = "_")] =0
}
}
i=i+1
}
}
return(df)
}
Chạy function b.dummy với df=data.frame, col: tên cột cần tách, sep: dấu dùng để tách các giá trị. Trong trường hợp của mình sep=";".
b.dummy(df,"flower_color",";")
id flower_color dummy_do dummy_xanh dummy_vang dummy_trang
1 1 do 1 0 0 0
2 2 xanh 0 1 0 0
3 3 vang 0 0 1 0
4 4 do;trang;xanh 1 1 0 1
5 5 xanh;vang 0 1 1 0
Hàm mình viết ra tạm thời chạy ổn với trường hợp trên. Nếu bạn nào có cách nào khác xin gởi thông tin cho mình tham khảo. Cảm ơn các bạn