【问题标题】:How to deal with column containing multiple comma-separated values in R language如何处理R语言中包含多个逗号分隔值的列
【发布时间】:2020-08-01 08:55:36
【问题描述】:

我的数据集(CSV 文件)中有一个列,即便利设施。它包含诸如{“无线互联网”、“轮椅可访问”、厨房、电梯、“蜂鸣器/无线对讲机”、暖气、洗衣机、烘干机、必需品、洗发水、衣架、笔记本电脑友好型工作区“}、{电视、有线电视”,互联网,无线上网”,空调”,厨房,“允许吸烟”,“允许携带宠物”,“蜂鸣器/无线对讲”,暖气,“家庭/儿童友好”,“烟雾探测器”,碳一氧化碳等。大约有 10k 列这样的。我想将每个便利设施转换为新列,并希望为每个条目创建 0 或 1 值。例如:

应按如下方式创建列。 无线上网轮椅可进入厨房电梯蜂鸣器/无线 1 0 1 1 0

基本上,列的每个元素都会创建一个新列,并且它们的值应该像 0 和 1 一样,这取决于列中是否存在便利设施。

我输入如下: enter image description here

我希望输出如下:

enter image description here

【问题讨论】:

  • 检查我的答案here。你应该能理解。
  • 这可能会帮助您入门:假设您的 daatframe 被称为df您可以这样做:amenities_clean <- gsub('[{}"]', '', df$amenities) # remove unwanted stuff amenities_unique <- unique(unlist(strsplit(amenities_clean, ","))) # get a list of unique amenities df[amenities_unique] <- NA # set up the columns for each amenity
  • @ChrisRuehlemann:感谢上述拆分代码。有效。现在我的目标是使用这些值在 df 中创建新列,如果该值在原始便利设施列中可用,则标记为 1 else 0。

标签: r one-hot-encoding


【解决方案1】:

这是一个(相当复杂的)解决方案(针对一个相当复杂的问题):

数据:

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_splitamenities_unique):

cbind(df, t(sapply(amenities_split, function(x) 
  table(factor(x, levels = amenities_unique)))))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-02
    • 2018-07-18
    • 2020-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-25
    相关资源
    最近更新 更多