这是一个(相当复杂的)解决方案(针对一个相当复杂的问题):
数据:
df <- data.frame(
id = 1:2,
amenities = c('{"Wireless Internet","Wheelchair accessible",Kitchen,Elevator,"Buzzer/wireless intercom",Heating,Washer,Dryer,Essentials,Shampoo,Hangers,"Laptop friendly workspace"}',
'{TV,"Cable TV",Internet,"Wireless Internet","Air conditioning",Kitchen,"Smoking allowed","Pets allowed","Buzzer/wireless intercom",Heating,"Family/kid friendly","Smoke detector","Carbon monoxide}'))
准备数据:
amenities_clean <- gsub('[{}"]', '', df$amenities) # remove unwanted stuff
amenities_split <- strsplit(amenities_clean, ",") # split rows into individual amenities
amenities_unique <- unique(unlist(strsplit(amenities_clean, ","))) # get a list of unique amenities
df[amenities_unique] <- NA # set up the columns for each amenity
现在进行分析,使用 stringr 包中的 str_detect:
# record presence/absence of individual amenities in each new column:
library(stringr)
for(i in 1:ncol(df[amenities_unique])){
for(j in 1:nrow(df)){
df[amenities_unique][j,i] <-
ifelse(str_detect(amenities_split[j], names(df[amenities_unique][i])), 1, 0)
}
}
这会提示警告,但它们似乎可以忽略不计,因为结果是正确的:
df
id
1 1
2 2
amenities
1 {"Wireless Internet","Wheelchair accessible",Kitchen,Elevator,"Buzzer/wireless intercom",Heating,Washer,Dryer,Essentials,Shampoo,Hangers,"Laptop friendly workspace"}
2 {TV,"Cable TV",Internet,"Wireless Internet","Air conditioning",Kitchen,"Smoking allowed","Pets allowed","Buzzer/wireless intercom",Heating,"Family/kid friendly","Smoke detector","Carbon monoxide}
Wireless Internet Wheelchair accessible Kitchen Elevator Buzzer/wireless intercom Heating Washer Dryer
1 1 1 1 1 1 1 1 1
2 1 0 1 0 1 1 0 0
Essentials Shampoo Hangers Laptop friendly workspace TV Cable TV Internet Air conditioning Smoking allowed
1 1 1 1 1 0 0 1 0 0
2 0 0 0 0 1 1 1 1 1
Pets allowed Family/kid friendly Smoke detector Carbon monoxide
1 0 0 0 0
2 1 1 1 1
编辑:
另外,也许更经济,而不是嵌套的 forloop,您可以使用这样的 apply 函数(基于第一个解决方案的准备阶段的向量 amenities_split 和 amenities_unique):
cbind(df, t(sapply(amenities_split, function(x)
table(factor(x, levels = amenities_unique)))))