2017-02-19 6 views
0

Я новичок в программировании R и задавался вопросом, могу ли я получить некоторую помощь в решении проблемы, на которой я застрял. В настоящее время у меня есть два кадра данных. Один из них - ign_temp, в котором есть список названий видеоигр (около 18 000) и соответствующая платформа, на которой они появляются (около 30 + типов). Есть несколько записей заглавия, которые появляются несколько раз из-за выпуска на нескольких платформах, как показано ниже. Этот df был просто отфильтрован, чтобы отображать только название и платформу из исходной базы данных, которая имеет множество столбцов (id, url, год выпуска и т. Д.).Назначение значений в dataframe на основе совпадающих столбцов между двумя различными кадрами данных (R)

ign_temp:

  title       platform 
      LittleBigPlanet     Playstation Vita   
      Splice       Playstation Vita  
      NHL 13       Xbox 
      NHL 13       Android 
      Wild       iPhone 
      Mark of the Ninja    Xbox 360 
      Mark of the Ninja    PC 
      ....... 

Я другой кадр данных, который имеет ign_revised образца набор игр от dataframe выше, но имеет дополнительные значения столбцов, как оценка, год и т.д. Каждая игра появляется только один раз в отчетливо строку и я добавил новые столбцы dataframe для возможной платформы они появляются на (после года колонка, начиная с Android будет Xbox One, около 24 платформы), как показано ниже (сгущенного вид):

ign_revised:

 id  score_phrase title  score genre year Android Arcade ... Xbox One 
     315 Cool   Abzu  7.5  Puzzle 2012 Android Arcade ... Xbox One 
     87  Poor   Alan  5.0  Action 2014 Android Arcade ... Xbox One 
     ..... 
     598 Great   NHL 13 8.5  Sports 2013 Android Arcade ... Xbox One 

Ign_revised в алфавитном порядке, а столбцы игровой платформы (Android Arcade .. XboxOne) просто повторяют имя платформы для всех 1600+ заголовков, которые появляются в этой области данных.

Мой главный вопрос: есть ли способ, подобный циклу for, который из ign_revised использует заголовок и столбцы платформы (Android Arcade ... XboxOne) для соответствия ign_temp с соответствующим заголовком и платформой и изменяет значения в столбцы ign_revised в Android Arcade ... XboxOne вместо этого показывает 1 (название видеоигры появляется на этой платформе) или 0, если это не так. Так это будет выглядеть как-то, как показано ниже:

ign_revised (окончательный результат):

 id  score_phrase title  score genre year Android Arcade ... Xbox One 
     315 Cool   Abzu  7.5  Puzzle 2012 0  1  ... 0 
     87  Poor   Alan  5.0  Action 2014 0  0  ... 1 
     ..... 
     598 Great   NHL 13 8.5  Sports 2013 1  0  ... 1 

В моей фактической ign_revised dataframe, название в названиях третьей колонки и платформы, начиная с Android является 12-й столбец, если помогает.

псевдокод:

for (i in 1:nrow(ign_revised)) { 

     for (j in 12:ncol(ign_revised)) { 

      * Match current title and platform to ign_temp 
      * Assign current cell (i,j) value with 1 or 0 based on match 

      } 
    } 

Спасибо!

@Gregor

EDIT 1: К сожалению, я не могу комментировать и правильно пространство из модифицированного кода в ответ комментарии, но так как ign_temp потребуется все 18,625 игр не только 7 перечисленных игры, которые у меня были выше от оригинала df, называемого (ign), следует ли мне изменить его на что-то вроде этого? :

all_title <- ign$title 

all_platform <- ign$platform 

ign_temp <- structure(list(title = all_title, platform = all_platform, .Names = c("title","platform"), row.names = c(1, -18625L), class = c("data.frame"))) 

ign_temp$value = 1 
ign_temp_wide = reshape2::dcast(title ~ platform, data = ign_temp,value.var = "value", fill = 0) 

merge(ign_revised[1:11], ign_temp_wide) 

Я не уверен, потому что я получаю ошибку:

Ошибка в повторении (1, nrow (данных)): аргумент недействительны 'времена'

EDIT 2: Добавление dput для ign_revised, ign_temp, ign_temp_wide.

dput(droplevels(head(ign_temp, 7))) 
structure(list(title = c("LittleBigPlanet PS Vita", "LittleBigPlanet PS Vita -- Marvel Super Hero Edition", 
"Splice: Tree of Life", "NHL 13", "NHL 13", "Total War Battles: Shogun", 
"Double Dragon: Neon"), platform = c("PlayStation Vita", "PlayStation Vita", 
"iPad", "Xbox 360", "PlayStation 3", "Macintosh", "Xbox 360"), 
value = c(1, 1, 1, 1, 1, 1, 1)), .Names = c("title", "platform", 
    "value"), row.names = c(NA, -7L), class = c("tbl_df", "tbl", 
    "data.frame")) 



dput(droplevels(head(ign_temp_wide, 7))) 

structure(list(title = c("#IDARB", "007 Legends", "1001 Spikes", 
"140", "1979 Revolution", "2014 FIFA World Cup Brazil", "3 Heroes -- Crystal Soul" 
), Android = c(0, 0, 0, 0, 0, 0, 0), Arcade = c(0, 0, 0, 0, 0, 
0, 0), iPad = c(0, 0, 0, 0, 0, 0, 0), iPhone = c(0, 0, 0, 0, 
0, 0, 0), Linux = c(0, 0, 0, 0, 0, 0, 0), Macintosh = c(0, 0, 
0, 0, 0, 0, 0), `New Nintendo 3DS` = c(0, 0, 0, 0, 0, 0, 0), 
    `Nintendo 3DS` = c(0, 0, 1, 0, 0, 0, 0), `Nintendo DS` = c(0, 
    0, 0, 0, 0, 0, 0), `Nintendo DSi` = c(0, 0, 0, 0, 0, 0, 1 
    ), Ouya = c(0, 0, 0, 0, 0, 0, 0), PC = c(0, 0, 1, 1, 1, 0, 
    0), `PlayStation 3` = c(0, 1, 0, 0, 0, 1, 0), `PlayStation 4` = c(0, 
    0, 1, 0, 0, 0, 0), `PlayStation Portable` = c(0, 0, 0, 0, 
    0, 0, 0), `PlayStation Vita` = c(0, 0, 1, 0, 0, 0, 0), SteamOS = c(0, 
    0, 0, 0, 0, 0, 0), `Web Games` = c(0, 0, 0, 0, 0, 0, 0), 
    Wii = c(0, 0, 0, 0, 0, 0, 0), `Wii U` = c(0, 1, 1, 0, 0, 
    0, 0), `Windows Phone` = c(0, 0, 0, 0, 0, 0, 0), `Windows Surface` = c(0, 
    0, 0, 0, 0, 0, 0), `Xbox 360` = c(0, 1, 0, 0, 0, 1, 0), `Xbox One` = c(1, 
    0, 0, 0, 0, 0, 0)), .Names = c("title", "Android", "Arcade", 
"iPad", "iPhone", "Linux", "Macintosh", "New Nintendo 3DS", "Nintendo 3DS", 
"Nintendo DS", "Nintendo DSi", "Ouya", "PC", "PlayStation 3", 
"PlayStation 4", "PlayStation Portable", "PlayStation Vita", 
"SteamOS", "Web Games", "Wii", "Wii U", "Windows Phone", "Windows Surface", 
"Xbox 360", "Xbox One"), row.names = c(NA, 7L), class = "data.frame") 

dput(droplevels(head(ign_revised, 7))) 
structure(list(X1 = c(18007L, 145L, 17730L, 17325L, 18475L, 17699L, 
16486L), score_phrase = c("Good", "Bad", "Great", "Great", "Great", 
"Good", "Mediocre"), title = c("#IDARB", "007 Legends", "1001 Spikes", 
"140", "1979 Revolution", "2014 FIFA World Cup Brazil", "3 Heroes -- Crystal Soul" 
), url = c("/games/it-draws-a-red-box/xbox-one-20014945", "/games/007-legends/xbox-360-132394", 
"/games/1001-spikes/wii-u-132248", "/games/140-game/pc-20007190", 
"/games/1979-the-game/pc-115360", "/games/2014-fifa-world-cup/ps3-20012688", 
"/games/3-heroes-crystal-soul/dsi-126064"), platform = c("Xbox One", 
"Xbox 360", "Wii U", "PC", "PC", "PlayStation 3", "Nintendo DSi" 
), score = c(7.5, 4.5, 8, 8, 8, 7.5, 5), genre = c("Party", "Action", 
"Platformer", "Platformer", "Action, Adventure", "Sports", "Adventure" 
), editors_choice = c("N", "N", "N", "N", "N", "N", "N"), release_year = c(2015L, 
2012L, 2014L, 2013L, 2016L, 2014L, 2012L), release_month = c(1L, 
10L, 6L, 10L, 4L, 4L, 1L), release_day = c(14L, 16L, 8L, 16L, 
21L, 17L, 5L), Android = c("Android", "Android", "Android", "Android", 
"Android", "Android", "Android"), Arcade = c("Arcade", "Arcade", 
"Arcade", "Arcade", "Arcade", "Arcade", "Arcade"), iPad = c("iPad", 
"iPad", "iPad", "iPad", "iPad", "iPad", "iPad"), iPhone = c("iPhone", 
"iPhone", "iPhone", "iPhone", "iPhone", "iPhone", "iPhone"), 
    Linux = c("Linux", "Linux", "Linux", "Linux", "Linux", "Linux", 
    "Linux"), Macintosh = c("Macintosh", "Macintosh", "Macintosh", 
    "Macintosh", "Macintosh", "Macintosh", "Macintosh"), `New Nintendo 3DS` = c("New Nintendo 3DS", 
    "New Nintendo 3DS", "New Nintendo 3DS", "New Nintendo 3DS", 
    "New Nintendo 3DS", "New Nintendo 3DS", "New Nintendo 3DS" 
    ), `Nintendo 3DS` = c("Nintendo 3DS", "Nintendo 3DS", "Nintendo 3DS", 
    "Nintendo 3DS", "Nintendo 3DS", "Nintendo 3DS", "Nintendo 3DS" 
    ), `Nintendo DS` = c("Nintendo DS", "Nintendo DS", "Nintendo DS", 
    "Nintendo DS", "Nintendo DS", "Nintendo DS", "Nintendo DS" 
    ), `Nintendo DSi` = c("Nintendo DSi", "Nintendo DSi", "Nintendo DSi", 
    "Nintendo DSi", "Nintendo DSi", "Nintendo DSi", "Nintendo DSi" 
    ), Ouya = c("Ouya", "Ouya", "Ouya", "Ouya", "Ouya", "Ouya", 
    "Ouya"), PC = c("PC", "PC", "PC", "PC", "PC", "PC", "PC"), 
    `PlayStation 3` = c("PlayStation 3", "PlayStation 3", "PlayStation 3", 
    "PlayStation 3", "PlayStation 3", "PlayStation 3", "PlayStation 3" 
    ), `PlayStation 4` = c("PlayStation 4", "PlayStation 4", 
    "PlayStation 4", "PlayStation 4", "PlayStation 4", "PlayStation 4", 
    "PlayStation 4"), `PlayStation Portable` = c("PlayStation Portable", 
    "PlayStation Portable", "PlayStation Portable", "PlayStation Portable", 
    "PlayStation Portable", "PlayStation Portable", "PlayStation Portable" 
    ), `PlayStation Vita` = c("PlayStation Vita", "PlayStation Vita", 
    "PlayStation Vita", "PlayStation Vita", "PlayStation Vita", 
    "PlayStation Vita", "PlayStation Vita"), SteamOS = c("SteamOS", 
    "SteamOS", "SteamOS", "SteamOS", "SteamOS", "SteamOS", "SteamOS" 
    ), `Web Games` = c("Web Games", "Web Games", "Web Games", 
    "Web Games", "Web Games", "Web Games", "Web Games"), Wii = c("Wii", 
    "Wii", "Wii", "Wii", "Wii", "Wii", "Wii"), `Wii U` = c("Wii U", 
    "Wii U", "Wii U", "Wii U", "Wii U", "Wii U", "Wii U"), `Windows Phone` = c("Windows Phone", 
    "Windows Phone", "Windows Phone", "Windows Phone", "Windows Phone", 
    "Windows Phone", "Windows Phone"), `Windows Surface` = c("Windows Surface", 
    "Windows Surface", "Windows Surface", "Windows Surface", 
    "Windows Surface", "Windows Surface", "Windows Surface"), 
    `Xbox 360` = c("Xbox 360", "Xbox 360", "Xbox 360", "Xbox 360", 
    "Xbox 360", "Xbox 360", "Xbox 360"), `Xbox One` = c("Xbox One", 
    "Xbox One", "Xbox One", "Xbox One", "Xbox One", "Xbox One", 
    "Xbox One")), .Names = c("X1", "score_phrase", "title", "url", 
"platform", "score", "genre", "editors_choice", "release_year", 
"release_month", "release_day", "Android", "Arcade", "iPad", 
"iPhone", "Linux", "Macintosh", "New Nintendo 3DS", "Nintendo 3DS", 
"Nintendo DS", "Nintendo DSi", "Ouya", "PC", "PlayStation 3", 
"PlayStation 4", "PlayStation Portable", "PlayStation Vita", 
"SteamOS", "Web Games", "Wii", "Wii U", "Windows Phone", "Windows Surface", 
"Xbox 360", "Xbox One"), row.names = c(NA, -7L), class = c("tbl_df", 
"tbl", "data.frame")) 

Я также проверил TYPEOF как для названия столбцов и от ФР, поскольку оба «характер»

typeof(ign_temp$title) 
[1] "character" 
> typeof(ign_revised$title) 
[1] "character" 

@Gregor Однако слияние еще не похоже на работу. Поскольку это было внутреннее соединение, я также попытался указать «title», но столбцы платформы по-прежнему остаются неизменными в ign_revised. Какие-либо предложения?

merge(ign_revised[1:11], ign_temp_wide, by = "title") 

ответ

0

Я бы первым бросил свой кадр ign_temp данных в широком формате, создавая фиктивные переменные, как вы хотите, а затем присоединиться к данным ign_revised.

Используя этот вход:

ign_temp = structure(list(title = c("LittleBigPlanet", "Splice", "NHL 13", 
"NHL 13", "Wild", "Mark of the Ninja", "Mark of the Ninja"), 
    platform = c("Playstation Vita", "Playstation Vita", "Xbox", 
    "Android", "iPhone", "Xbox 360", "PC")), .Names = c("title", 
"platform"), row.names = c(NA, -7L), class = c("data.frame")) 

ign_temp$value = 1 
ign_temp_wide = reshape2::dcast(title ~ platform, data = ign_temp, 
          value.var = "value", fill = 0) 
ign_temp_wide 
#    title Android iPhone PC Playstation Vita Xbox Xbox 360 
# 1 LittleBigPlanet  0  0 0    1 0  0 
# 2 Mark of the Ninja  0  0 1    0 0  1 
# 3   NHL 13  1  0 0    0 1  0 
# 4   Splice  0  0 0    1 0  0 
# 5    Wild  0  1 0    0 0  0 

Тогда присоединяйтесь просто. Это должно работать:

merge(ign_revised[1:11], ign_temp_wide) 

Вам просто нужно внутреннее соединение здесь между не-платформенными колоннами из ign_revised (я использовал 1:11, так как вы говорите платформы начинаются в 12-м столбца) и полнотой ign_temp_wide. base::merge работает, но вы можете выбрать свой любимый метод от How to join in R. Если у вас возникли проблемы с соединением, убедитесь, что title - столбец класса character в обоих кадрах данных. Я также предполагаю, что имя столбца "title" одинаково в обоих кадрах данных.

+0

Извините, я не могу добавить свой измененный вопрос в ответ на комментарий, поэтому добавили его в Редактировать в главном сообщении, если все в порядке. Спасибо, что помогли мне. – DubCode

+0

* Вы * можете игнорировать бит 'structure()' в моем ответе - после того, как я прочитал ваши данные (что заняло немного немного из-за пробелов в некоторых значениях), я запустил 'dput (ign_temp)', который создал значения 'structure (list (title = ...))'. Это хороший способ обмена данными, потому что это копирование/вставка - это [как мы обычно предпочитаем, чтобы данные были разделены для вопросов R) (http://stackoverflow.com/q/5963269/903061), но это только для обмена данными. Он просто пытается реплицировать любой кадр данных, который у вас уже есть. – Gregor

+0

Вы должны уметь пропустить эту строку и запустить остальную часть кода в фрейме данных 'ign_temp', который у вас уже есть. Идеальный способ обмена данными в вашем вопросе состоял бы в том, чтобы опубликовать код для 'dput (droplevels (head (ign_temp, 7))) - таким образом я мог бы скопировать/вставить ваш фрейм данных в свою R-сессию и убедитесь, что структура была точно такой же. – Gregor

Смежные вопросы