#r #dataframe #if-statement #match
#r #фрейм данных #if-statement #совпадение
Вопрос:
Я пытаюсь, используя данные бейсбольной игры retrosheet, присвоить имя кэтчеру для любого заданного броска, сделанного в эпоху pitfx. Я использовал ifelse для запуска серии тестов, чтобы найти стартовый ловец. Код и ошибки приведены ниже — также я намерен после того, как это заработает, вместо вывода «нет» в случае сбоя, вложить в это аналогичные тесты ifelse, пока я не перейду с HmBat1Pos на HmBat9Pos … и т.д.
atbat$starting_catcher_retro = ifelse(((atbat$date = retro_games$Date)
amp; (atbat$pitcher_name = retro_games$HmStPchNm)
amp; (atbat$num = 1)
amp; (atbat$inning_side = "top")
amp; (retro_games$HmBat1Pos = 2)),
retro_games$HmBat1ID, "no")
ошибки
Error in `$<-.data.frame`(`*tmp*`, date, value = c(13963, 13964, 13968, :
replacement has 26726 rows, data has 2146373
Затем я попытался удалить часть кода, проверяющего дату, и все равно получил ошибки. Поэтому я запустил это вместо
atbat$starting_catcher_retro = ifelse(((atbat$num = 1)
amp; (atbat$inning_side = "top")
amp;(retro_games$HmBat1Pos = 2)),
retro_games$HmBat1ID, "no")
и получил эти другие ошибки
Error in (atbat$num = 1) amp; (atbat$inning_side = "top") :
operations are possible only for numeric, logical or complex types
ответ на комментарии
это был код, который я добавил, и возвращенная ошибка
> merged_df <- merge(atbat, retro_games,
by.x = c("date", "pitcher_name"),
by.y = c("Date", "HmStPchNm"), all.x = FALSE)
>
> merged_df$starting_catcher_retro = with(merged_df,
ifelse((num == 1)
amp; (inning_side == "top")
amp; (HmBat3Pos == 2),
HmBat3ID, "no"))
>
> atbat$starting_catcher_retro <- merged_df$starting_catcher_retro[match(merged_df$unique_id, atbat$unique_id)]
Error in `$<-.data.frame`(`*tmp*`, starting_catcher_retro, value = c("no", :
replacement has 566448 rows, data has 2146373
Я также попытался применить подход, отличный от описанного выше, который основан на идее, которая пришла мне в голову — ниже приведен этот код и возвращенные ошибки, в которых все выглядит так, как будто должно работать, но даже не создан новый столбец
atbat$starting_catcher_retro = ifelse(((retro_games$Date %in% atbat$date)
amp; (retro_games$HmStPchNm %in% atbat$pitcher_name)
amp; (atbat$inning_side == "top")
amp; (retro_games$HmBat1Pos == 2)),
retro_games$HmBat1ID,
ifelse(((retro_games$Date %in% atbat$date)
amp; (retro_games$HmStPchNm %in% atbat$pitcher_name)
amp; (atbat$inning_side == "top")
amp; (retro_games$HmBat2Pos == 2)),
retro_games$HmBat2ID,
ifelse(((retro_games$Date %in% atbat$date)
amp; (retro_games$HmStPchNm %in% atbat$pitcher_name)
amp; (atbat$inning_side == "top")
amp; (retro_games$HmBat3Pos == 2)),
retro_games$HmBat3ID,
ifelse(((retro_games$Date %in% atbat$date)
amp; (retro_games$HmStPchNm %in% atbat$pitcher_name)
amp; (atbat$inning_side == "top")
amp; (retro_games$HmBat4Pos == 2)),
retro_games$HmBat4ID,
ifelse(((retro_games$Date %in% atbat$date)
amp; (retro_games$HmStPchNm %in% atbat$pitcher_name)
amp; (atbat$inning_side == "top")
amp; (retro_games$HmBat5Pos == 2)),
retro_games$HmBat5ID,
ifelse(((retro_games$Date %in% atbat$date)
amp; (retro_games$HmStPchNm %in% atbat$pitcher_name)
amp; (atbat$inning_side == "top")
amp; (retro_games$HmBat6Pos == 2)),
retro_games$HmBat6ID,
ifelse(((retro_games$Date %in% atbat$date)
amp; (retro_games$HmStPchNm %in% atbat$pitcher_name)
amp; (atbat$inning_side == "top")
amp; (retro_games$HmBat7Pos == 2)),
retro_games$HmBat7ID,
ifelse(((retro_games$Date %in% atbat$date)
amp; (retro_games$HmStPchNm %in% atbat$pitcher_name)
amp; (atbat$inning_side == "top")
amp; (retro_games$HmBat8Pos == 2)),
retro_games$HmBat8ID,
ifelse(((retro_games$Date %in% atbat$date)
amp; (retro_games$HmStPchNm %in% atbat$pitcher_name)
amp; (atbat$inning_side == "top")
amp; (retro_games$HmBat9Pos == 2)),
retro_games$HmBat9ID,
ifelse(((retro_games$Date %in% atbat$date)
amp; (retro_games$VisStPchNm %in% atbat$pitcher_name)
amp; (atbat$inning_side == "bottom")
amp; (retro_games$VisBat1Pos == 2)),
retro_games$VisBat1ID,
ifelse(((retro_games$Date %in% atbat$date)
amp; (retro_games$VisStPchNm %in% atbat$pitcher_name)
amp; (atbat$inning_side == "bottom")
amp; (retro_games$VisBat2Pos == 2)),
retro_games$VisBat12D,
ifelse(((retro_games$Date %in% atbat$date)
amp; (retro_games$VisStPchNm %in% atbat$pitcher_name)
amp; (atbat$inning_side == "bottom")
amp; (retro_games$VisBat3Pos == 2)),
retro_games$VisBat3ID,
ifelse(((retro_games$Date %in% atbat$date)
amp; (retro_games$VisStPchNm %in% atbat$pitcher_name)
amp; (atbat$inning_side == "bottom")
amp; (retro_games$VisBat4Pos == 2)),
retro_games$VisBat4ID,
ifelse(((retro_games$Date %in% atbat$date)
amp; (retro_games$VisStPchNm %in% atbat$pitcher_name)
amp; (atbat$inning_side == "bottom")
amp; (retro_games$VisBat5Pos == 2)),
retro_games$VisBat5ID,
ifelse(((retro_games$Date %in% atbat$date)
amp; (retro_games$VisStPchNm %in% atbat$pitcher_name)
amp; (atbat$inning_side == "bottom")
amp; (retro_games$VisBat6Pos == 2)),
retro_games$VisBat6ID,
ifelse(((retro_games$Date %in% atbat$date)
amp; (retro_games$VisStPchNm %in% atbat$pitcher_name)
amp; (atbat$inning_side == "bottom")
amp; (retro_games$VisBat7Pos == 2)),
retro_games$VisBat7ID,
ifelse(((retro_games$Date %in% atbat$date)
amp; (retro_games$VisStPchNm %in% atbat$pitcher_name)
amp; (atbat$inning_side == "bottom")
amp; (retro_games$VisBat8Pos == 2)),
retro_games$VisBat8ID,
ifelse(((retro_games$Date %in% atbat$date)
amp; (retro_games$VisStPchNm %in% atbat$pitcher_name)
amp; (atbat$inning_side == "bottom")
amp; (retro_games$VisBat9Pos == 2)),
retro_games$VisBat9ID, ""))))))))))))))))))
и ошибка
Error in ans[test amp; ok] <- rep(yes, length.out = length(ans))[test amp; ok] :
replacement has length zero
In addition: There were 23 warnings (use warnings() to see them)
> warnings()
Warning messages:
1: In (retro_games$Date %in% atbat$date) amp; (retro_games$HmStPchNm %in% ... :
longer object length is not a multiple of shorter object length
2: In (retro_games$Date %in% atbat$date) amp; (retro_games$HmStPchNm %in% ... :
longer object length is not a multiple of shorter object length
3: In (retro_games$Date %in% atbat$date) amp; (retro_games$HmStPchNm %in% ... :
longer object length is not a multiple of shorter object length
4: In (retro_games$Date %in% atbat$date) amp; (retro_games$HmStPchNm %in% ... :
longer object length is not a multiple of shorter object length
5: In (retro_games$Date %in% atbat$date) amp; (retro_games$HmStPchNm %in% ... :
longer object length is not a multiple of shorter object length
6: In (retro_games$Date %in% atbat$date) amp; (retro_games$HmStPchNm %in% ... :
longer object length is not a multiple of shorter object length
7: In (retro_games$Date %in% atbat$date) amp; (retro_games$HmStPchNm %in% ... :
longer object length is not a multiple of shorter object length
8: In (retro_games$Date %in% atbat$date) amp; (retro_games$HmStPchNm %in% ... :
longer object length is not a multiple of shorter object length
9: In (retro_games$Date %in% atbat$date) amp; (retro_games$HmStPchNm %in% ... :
longer object length is not a multiple of shorter object length
10: In (retro_games$Date %in% atbat$date) amp; (retro_games$HmStPchNm %in% ... :
longer object length is not a multiple of shorter object length
11: In (retro_games$Date %in% atbat$date) amp; (retro_games$HmStPchNm %in% ... :
longer object length is not a multiple of shorter object length
12: In (retro_games$Date %in% atbat$date) amp; (retro_games$HmStPchNm %in% ... :
longer object length is not a multiple of shorter object length
13: In (retro_games$Date %in% atbat$date) amp; (retro_games$HmStPchNm %in% ... :
longer object length is not a multiple of shorter object length
14: In (retro_games$Date %in% atbat$date) amp; (retro_games$HmStPchNm %in% ... :
longer object length is not a multiple of shorter object length
15: In (retro_games$Date %in% atbat$date) amp; (retro_games$HmStPchNm %in% ... :
longer object length is not a multiple of shorter object length
16: In (retro_games$Date %in% atbat$date) amp; (retro_games$HmStPchNm %in% ... :
longer object length is not a multiple of shorter object length
17: In (retro_games$Date %in% atbat$date) amp; (retro_games$HmStPchNm %in% ... :
longer object length is not a multiple of shorter object length
18: In (retro_games$Date %in% atbat$date) amp; (retro_games$HmStPchNm %in% ... :
longer object length is not a multiple of shorter object length
19: In (retro_games$Date %in% atbat$date) amp; (retro_games$VisStPchNm %in% ... :
longer object length is not a multiple of shorter object length
20: In (retro_games$Date %in% atbat$date) amp; (retro_games$VisStPchNm %in% ... :
longer object length is not a multiple of shorter object length
21: In (retro_games$Date %in% atbat$date) amp; (retro_games$VisStPchNm %in% ... :
longer object length is not a multiple of shorter object length
22: In (retro_games$Date %in% atbat$date) amp; (retro_games$VisStPchNm %in% ... :
longer object length is not a multiple of shorter object length
23: In rep(yes, length.out = length(ans)) :
'x' is NULL so the result will be NULL
правка2
выборка из обоих фреймов данных из первых 15 строк была слишком длинной для включения, вот ее фрагмент — https://pastebin.com/kTVEgdRs
Комментарии:
1. Ваш логический тест должен использовать
==
вместо=
, верно? это помогает?2. @liuminzhao Моя ошибка новичка, ты прав, это помогает… единственная проблема сейчас в том, что весь столбец заполнен только «no», даже когда я запускаю его для всей линейки…
Ответ №1:
Обычно ifelse
выполняется в одном фрейме данных, обеспечивая равное количество строк не во всех наборах данных. Сначала рассмотрите возможность объединения, а затем запустите ifelse
. Ниже выполняется объединение по левому краю, сохраняя все строки в atbat.
merged_df <- merge(atbat, retro_games,
by.x = c("date", "pitcher_name"),
by.y = c("Date", "HmStPchNm"), all.x = TRUE)
merged_df$starting_catcher_retro = with(merged_df,
ifelse((num == 1)
amp; (inning_side == "top")
amp; (HmBat1Pos == 2),
HmBat1ID, "no")
)
Комментарии:
1. Это выглядит намного проще, чем то, что я пытался, но при использовании этого я столкнулся с двумя проблемами — первая заключается в том, что при ручной перекрестной проверке нескольких ловушек, просматривая atbat, а затем просматривая retrosheet, я получал неправильные идентификаторы, где некоторые были игроками, которые вообще не ловят, вторая — ошибка в чем-то, что я добавил, чтобы переместить те же данные из объединенного фрейма данных в фрейм данных atbat — все выше в моем отредактированном исходном сообщении.
2. Глядя на вашу
merge
попытку, вы повторяете ту же ошибку назначенияifelse
во фреймах данных. Не делайте этого. Иmerge
может даже сократить вашу вложенностьifelse
. Пожалуйстаdput
, небольшой пример обоих фреймов данных и желаемого результата.3. Вот ссылка pasetbin на dput первых 15 строк обоих — pastebin.com/kTVEgdRs — что касается моего желаемого результата, я просто хочу столбец в atbat с именем кетчера только в том, что будет первым на bat, потому что тогда я могу установить этот кетчер для всей игры, используя комбинацию gamelink и какой стороны подачи (верхней или нижней). У меня есть отдельный файл от pitchfx, в котором есть защитные замены, которые я могу затем использовать для обновления имени ловца для каждой игры в зависимости от подачи и от того, было ли на самом деле изменение, как только я узнаю стартера.
4. В вашей ссылке есть только
dput
of atbat .5. Я также не совсем понимаю, что вы имеете в виду, говоря, что я повторяю ту же ошибку