Подмножество наборов данных по переменной, прежде чем использовать expand.grid для расчета матрицы расстояний - PullRequest
0 голосов
/ 26 ноября 2018

У меня есть два набора данных.Один набор данных имеет около 30 тыс. Строк, а второй набор содержит около 60 тыс. Строк.Меньший набор данных (df1) имеет уникальный идентификатор (upc), который имеет решающее значение для моего анализа.

У большего набора данных (df2) нет , этот уникальныйидентификатор, но у него есть описательная переменная (product_title), которую можно сопоставить с аналогичной переменной описания в df1 и использовать для вывода уникального идентификатора.

Я пытаюсь упростить ситуацию, поэтомуЯ использовал expand.grid.

df1_titles<-unique(df1$product_title) # List of 30k titles
df2_titles<-unique(df2$product_title) # List of 60k titles
r<- expand.grid(df1_titles,df2_titles) # Distance matrix 
names(r) <- c("df1_titles","df2_titles") 
r$dist <- stringdist(r$df1_titles,r$df2_titles, method="jw") # Calculate distance
r<-r[order(r$dist),] 
r<-r[!duplicated(r$df1_titles),] 
r<-subset(r,dist<.10)

К сожалению, R пытается расширить такую ​​большую сетку.Итак, у меня была идея использовать в обоих наборах данных вторую переменную (c1), чтобы ограничить expand.grid аналогичными элементами.Давайте предположим, что значения для category одинаковы для обоих наборов данных.

Хотя я знаю, что не рекомендовал для создания фреймов данных с использованием цикла, я не сделалУ меня есть лучшее представление о том, как задать подмножество данных для expand.grid, поэтому я все равно попробовал этот подход:

categories<-c("Beauty","Personal Care","Grocery","Household Essentials") # Variable with categories to subset

for (i in seq_along(categories)) {
  df1_sub<-subset(wmt,category==categories[i])
  df2_sub<-subset(m,category==categories[i])
  df1_titles<-unique(df1_sub$product_title)
  df2_titles<-unique(df2_sub$product_title)
  ### HOW DO I CREATE A LIST/GRID DYNAMICALLY? ### <-expand.grid(df1_titles,df2_titles)
}

После создания этих сеток планировалось бы получить уникальный идентификатор upc из df1 и присвойте ему совпадения в df2 перед консолидацией наборов данных.

Я уверен, что есть лучший способ сделать это, и надеюсь, что выявление лучшего способа уменьшить data.frames до соответствующих подмножеств передиспользование expand.grid будет полезно для других!

dput(sample_n(subset(df1,select=c(product_title,c1)),50)) structure(list(product_title = c("Sriracha Hot Chili Sauce Single Packets 25 Count .25 oz each (3 Items Per Order, not per case)",  "Duncan Hines Double Fudge Decadent Brownie Mix 17.6 oz by Duncan Hines",  "Mikee Tropical Teriyaki Sauce, 20 oz, (Pack of 12)", "NESQUIK Strawberry Low Fat Milk 6-8 fl. oz. Bottles",  "Dove Nutritive Solutions Conditioner, Coconut & Hydration 12 oz (Pack of 12)",  "FLORATA 24\" Long Straight Velcro Wrap Around Ponytail Hair Extensions",  "Bing Cherries, Dried (16 oz, ZIN: 527111) - 3-Pack", "San-J Tamari Brown Sesame Crackers, 3.7 oz (Pack of 12)",  "PERDUE HARVESTLAND Breaded Chicken Breast Nugget (22 oz.)",  "Fray Bentos Just Chicken Pie (425g) - Pack of 6", "Product of Thomas Coffee Regular Roast, Portion Packs (64 ct.) - Ground Coffee [Bulk Savings]", "Bombay Basmati Rice White, 2 LB (Pack of 12)", "Herbs for Kids, Sugar Free Elderberry Syrup, Cherry-Berry Flavor, 4 fl oz (pack of 3)",  "Grain Millers BG13916 Grain Millers Rolled Oats No. 5 - 1x50LB",  "Tuning Fork C 512 C512 SURGICAL MEDICAL INSTRUMENTS NEW", "Garnier Fructis Style Pure Clean Finishing Paste, All Hair Types, 2 oz. (Packaging May Vary) (Pack of 8)",  "Stretch Island Organic Fruit Strips Grape -- 6 Pocket-Sized Fruit Strips pack of 6",  "Torani Cinnamon Syrup 750ml", "JFC Nori Maki Arare Crackers 3 oz each (6 Items Per Order)",  "FLORATA Ponytail Buns Wrap Bun Chignon Hair Extensions Wavy Curly Wedding Donut Hair Extensions Hairpiece Wig",  "Kenra Platinum Hot Spray #20 8oz, PACK OF 8", "GBS Red and Black Shampoo Scalp Massage Brushes Plus 1 Soft Pocket Brush Made In USA 3 Pack Promotes Healthy Hair Growth Compliments Any Shampoo and Conditioner",  "Clairol Professional Creme Permanent Developer - 20 volume (Size : 2 oz)",  "Garnier Nutrisse Ultra Color Permanent Haircolor R3 Light Intense Auburn 1.0 ea(pack of 12)",  "Kemps Swiss Style Chocolate Low Fat Milk, 1 gal", "Aussie Kids 3n1 Shampoo, Conditioner, & Bodywash with Pump Coral Reef Cupcake 29.2 oz.(pack of 4)",  "Dequmana Gordal Olives, 12 Oz", "Duncan Hines Caramel Creamy Home-Style Frosting 16 Oz Canister",  "Goya Goya Mole, 9 oz", "Fruit Roll-Ups Fruit Flavored Snacks Variety Pack (Pack of 16)",  "Wild Huckleberry Mountain Huckleberry Barbecue Sauce", "La Flor Spicy Hot Seasoned Salt, 13 oz",  "Clairol Nice n Easy Hair Color #79 Dark Brown, UK Loving Care (Pack of 3) + Beyond BodiHeat Patch, 1 Ct",  "White Vinegar Liquid ''1 gallon, 4 Count, Liquid''", "Metallic Gold Dried Canella Berries - 6 oz Bunch",  "La Flor Adobo All-Purpose Seasoning, 13 oz", "Marlos Bakeshop Marlos Bakeshop Biscotti, 1.25 oz",  "Sam's Choice Frozen Burrito Bowl, Fajita Vegetable, 12.5 oz",  "Conchita guava marmalade 14.1 oz Pack of 3", "HC Industries Kids Organics Kids Organics Shampoo, 12 oz",  "6 Pack - Head & Shoulders Full & Thick 2-in-1 Anti-Dandruff Shampoo + Conditioner 32.1 oz",  "Ice Breakers, Wintergreen Mints Tin, 1.5 Oz (Pack of 8)", "Mason Pearson - Boar Bristle & Nylon - Medium Junior Military Nylon & Bristle Hair Brush (Dark Ruby) -1pc",  "Dove Nutritive Solutions Revival Cleansing Shampoo, 20.4 oz",  "Boston's Best 12 Ct Jamaican Me Crazy", "Ultimate Baker Edible Glitter Mix It Up (1x3oz)",  "Nori Maki Arare Rice Crackers with Seaweed 5 oz per Pack (1 Pack)",  "H&S 2in1 MENS REFRESH POO 13.5oz-Pack of 5", "Keebler Club Mini Crackers, Multi-Grain, 11 Ounce (Pack of 20)",  "Briess Sparkling Amber Liquid Malt Extract (30 Pound Pail)"), 
    c1 = c("Grocery", "Grocery", "Grocery", "Grocery", "Personal Care", 
    "Beauty", "Grocery", "Grocery", "Grocery", "Grocery", "Grocery", 
    "Grocery", "Grocery", "Grocery", "Beauty", "Beauty", "Grocery", 
    "Grocery", "Grocery", "Beauty", "Beauty", "Beauty", "Beauty", 
    "Beauty", "Grocery", "Beauty", "Grocery", "Grocery", "Grocery", 
    "Grocery", "Grocery", "Grocery", "Beauty", "Grocery", "Grocery", 
    "Grocery", "Grocery", "Grocery", "Grocery", "Personal Care", 
    "Beauty", "Grocery", "Beauty", "Beauty", "Grocery", "Grocery", 
    "Grocery", "Beauty", "Grocery", "Grocery")), row.names = c(16523L,  111871L, 28667L, 32067L, 8269L, 11076L, 50328L, 47200L, 99415L,  100031L, 39011L, 104854L, 29516L, 104643L, 3486L, 9689L, 52157L,  28995L, 47000L, 10895L, 3035L, 4992L, 3589L, 4276L, 32212L, 6055L,  22991L, 110279L, 27436L, 52282L, 14879L, 25710L, 6989L, 30133L,  51068L, 25490L, 45685L, 99073L, 18547L, 4991L, 5792L, 36241L,  10237L, 1430L, 40383L, 112458L, 46261L, 5875L, 46597L, 108099L ), class = "data.frame")

dput(sample_n(subset(df2,select=c(product_title,c1)),50))
structure(list(product_title = c("Drive Medical Heavy Duty Bariatric Plastic Seat Transfer Bench", 
"Always Pure & Clean Ultra Thin Feminine Pads With Wings, Super Long", 
"Patriot Candles Jar Candle Apple Clove Red", "Nature's Bounty Cardio-Health Probiotic Capsules", 
"Finest Nutrition Biotin Plus Keratin", "Dr. Scholl's DuraGel Corn Remover", 
"Humm Coconut Lime Kombucha 14 oz", "OneTouch Ultra Blue Test Strips", 
"Kellogg's Rice Krispies Treats Bars M&M's", "Westbrae Natural Organic Chili Beans", 
"Neutrogena Rapid Clear Acne Eliminating Spot Treatment Gel - 0.5 fl oz", 
"Harris Bed Bug Killer", "Quart Storage Bags - 80ct - Up&Up cent (Compare to Ziploc Storage Bags)", 
"Care Free Curl Gold Instant Curl Activator", "Purple Dessert Plate", 
"Wexford Big Bubble Plastic Mailer 2", "L'Oreal Paris Advanced Haircare Total Repair Extreme Emergency Recovery Mask", 
"Soap & Glory Spectaculips Matteallic Lip Cream Bronze Girl,Bronze Girl", 
"No7 Instant Results Purifying Heating Mask - 2.5oz", "NuMe Classic Curling Wand", 
"Revlon ColorSilk ColorStay Nourishing Conditioner Glowing Blonde", 
"Weiman Lemon Oil Furniture Polish Lemon", "Dunkin' Donuts Ground Coffee Hazelnut", 
"CocoaVia Cocoa Extract 375mg, Capsules", "Triple Paste AF Antifungal Ointment", 
"Welch's Halloween Fruit Snacks 0.5oz 28 ct", "Studio 35 Purifying Natural Facial Wipes", 
"Magnum Double Raspberry Mini Ice Cream Bars - 3ct", "CHI Twisted Fabric Finishing Paste", 
"Creme Of Nature Argan Oil Intensive Conditioning Hair Treatment", 
"Exergen Temporal Artery Thermometer", "Tolerex Formulated Liquid Diet Elemental Powder 6 Pack Unflavored", 
"Gerber Nature Select 2nd Foods Nutritious Dinner Baby Food Chicken Noodle", 
"Abreva Cold Sore Cream", "Super Macho Vitality and Stamina Dietary Supplement Softgel", 
"M&M's Peanut Chocolates Halloween Ghoul's Mix - 3.27oz", "TruMoo protein milk cookies n' cream - 14 fl oz", 
"DISNEY 25 Inch Plush Toy Assorted", "Beauty Infusion HYDRATING Manuka Honey & Collagen Sheet Mask", 
"Edge Shave Gel, Twin Pack Sensitive Skin", "Haribo Sour Gold Bears Resealable Stand Up Pouch Pineapple", 
"Jarrow Formulas Extra Virgin Coconut Oil, 1000mg, Softgels", 
"Bliss Pore Patrol Oil-Free Hydrator with Willow Bark - 1.7oz", 
"Airheads Candy Bites Watermelon", "Thrive Market Organic Sprouted Quinoa", 
"Garnier Fructis Curl Stretch Loosening Pudding", "Systane Nighttime Lubricant Eye Ointment", 
"SOHO Resort Organizer", "Enfamil Enfacare Lipil Infant Formula Powder", 
"Fancy Feast Flaked Gourmet Cat Food Tuna"), c1 = c("Home Health Care Solutions", 
"Personal Care", "Household Essentials", "Vitamin & Supplements", 
"Vitamin & Supplements", "Personal Care", "Grocery", "Home Health Care Solutions", 
"Grocery", "Grocery", "Beauty", "Household Essentials", "Household Essentials", 
"Beauty", "Household Essentials", "Household Essentials", "Beauty", 
"Beauty", "Beauty", "Beauty", "Beauty", "Household Essentials", 
"Grocery", "Vitamin & Supplements", "Personal Care", "Grocery", 
"Beauty", "Grocery", "Beauty", "Personal Care", "Personal Care", 
"Home Health Care Solutions", "Grocery", "Personal Care", "Vitamin & Supplements", 
"Grocery", "Grocery", "Baby, Kids & Toys", "Beauty", "Personal Care", 
"Grocery", "Vitamin & Supplements", "Beauty", "Grocery", "Grocery", 
"Beauty", "Personal Care", "Beauty", "Grocery", "Household Essentials"
)), row.names = c(39590L, 6987L, 13810L, 19403L, 26966L, 446L, 
41599L, 28238L, 7622L, 19653L, 16458L, 18164L, 738L, 19819L, 
43731L, 13310L, 17113L, 29729L, 29725L, 38903L, 25464L, 10048L, 
42932L, 41179L, 37568L, 5830L, 14276L, 20526L, 31614L, 20119L, 
40084L, 25978L, 1573L, 25121L, 3660L, 8850L, 10201L, 43313L, 
17973L, 40423L, 10299L, 37320L, 32177L, 18491L, 32860L, 30439L, 
24518L, 21579L, 24597L, 14687L), class = "data.frame")

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

Рассмотрите возможность расширения вашего подхода expand.grid и создайте список фреймов данных вложенных объединенных элементов.Затем связать строки сразу за пределами цикла.

# Variable with categories to subset
categories <- c("Beauty", "Personal Care", "Grocery", "Household Essentials") 

df_list <- vector("list", length = length(categories))

for (i in seq_along(categories)) {
  df1_sub <- subset(wmt, category == categories[i])
  df2_sub <- subset(m, category == categories[i])
  df1_titles <- unique(df1_sub$product_title)
  df2_titles <- unique(df2_sub$product_title)

  ### HOW DO I CREATE A LIST/GRID DYNAMICALLY?     
  r <-  expand.grid(df1_titles=df1_titles, df2_titles=df2_titles, stringsAsFactors=FALSE)     

  r$dist  <- stringdist(r$df1_titles, r$df2_titles, method="jw") 
  r <- r[order(r$dist),] 
  r <- r[!duplicated(r$df1_titles),] 
  r <- subset(r, dist<.10)

  # ASSIGN NESTED MERGE
  df_list[i] = merge(merge(r, df1, by.x="df1_title", by.y="product_title"), 
                     df2, by.x="df2_title", by.y="product_title")
}

# ROW BIND ALL DF ELEMENTS
final_df <- do.call(rbind, df_list)
0 голосов
/ 26 ноября 2018

Твоя идея хороша.Одна реализация этого будет тогда

df2$upc <- NA
for(ctg in unique(df2$c1)) {
  d <- stringdistmatrix(df1[df1$c1 == ctg, "product_title"], df2[df2$c1 == ctg, "product_title"], method = "jw")
  fuzz <- apply(d, 2, min)
  passThr <- fuzz < 0.1
  df2$fuzz[df2$c1 == ctg] <- fuzz
  df2$upc[df2$c1 == ctg][passThr] <- df1[df1$c1 == ctg, "upc"][apply(d, 2, which.min)][passThr]
}

Таким образом, для каждой строки в df2 ему присваивается значение upc из df1, у которого product.title_r имеет наименьшее расстояние от соответствующего product_title от df2.Насколько хорошо это работает, будет зависеть от количества категорий length(unique(df2$c1)).Чем их больше, тем быстрее цикл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...