#r #dplyr
#r #dplyr
Вопрос:
Я пытаюсь создать новый столбец, который преобразует код FIPS в аббревиатуру состояния, используя library (usmap), проблема в том, что новый столбец после использования mutate не соответствует размеру матрицы. После использования fips_info в новом столбце будет только 51 строка, но не 23570 строк исходной матрицы.
Ценю любую помощь, спасибо!
#defined function to get state abb
fips_function <- function(fips_code){
return (fips_info(fips_code)$abbr)
}
atus_19_selected <- act_19 %>%
mutate(state_abb = fips_function(GESTFIPS))
Error: Problem with `mutate()` input `state_abb`.
x Input `state_abb` can't be recycled to size 23570.
ℹ Input `state_abb` is `fips_function(GESTFIPS)`.
ℹ Input `state_abb` must be size 23570 or 1, not 51.
atus_19_selected
# A tibble: 23,570 x 8
GESTFIPS GTCO TUCASEID t150701 t150799 t150801 t150899 t159999
<dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 40 000 2.02e13 60 0 0 0 0
2 51 153 2.02e13 40 0 0 0 260
Ответ №1:
Проблема может заключаться в том, что некоторые значения являются дубликатами, поэтому он вернет ошибку. Одним из вариантов является rowwise
library(usmap)
library(dplyr)
act_19 %>%
rowwise %>%
mutate(state_abb = fips_function(GESTFIPS)) %>%
ungroup
-вывод
# A tibble: 3 x 2
# GESTFIPS state_abb
# <dbl> <chr>
#1 40 OK
#2 51 VA
#3 40 OK
Или другой вариант — выполнить это для distinct
значений ‘GESTFIPS’, а затем выполнить объединение
act_19 %>%
distinct(GESTFIPS) %>%
mutate(state_abb = fips_function(GESTFIPS)) %>%
right_join(act_19)
-вывод
# A tibble: 3 x 2
# GESTFIPS state_abb
# <dbl> <chr>
#1 40 OK
#2 40 OK
#3 51 VA
Ошибка может быть воспроизведена с повторяющимися значениями
act_19 %>%
mutate(state_abb = fips_function(GESTFIPS))
Ошибка: проблема с
mutate()
вводомstate_abb
.
✖ Входныеstate_abb
данные не могут быть переработаны до размера 3.
ℹ Вводstate_abb
fips_function(GESTFIPS)
.
ℹ Входныеstate_abb
данные должны иметь размер 3 или 1, а не 2.
Запуститеrlang::last_error()
, чтобы увидеть, где произошла ошибка.
Эта проблема возникает непосредственно из подмножества
usmap:::get_fips_info
function (fips)
{
if (all(nchar(fips) == 2)) {
df <- utils::read.csv(system.file("extdata", "state_fips.csv",
package = "usmap"), colClasses = rep("character",
3), stringsAsFactors = FALSE)
result <- df[df$fips %in% fips, ] # -> would subset only for unique fips
...
данные
act_19 <- tibble(GESTFIPS = c(40, 51, 40))
Ответ №2:
Когда fips_info
по какой-либо причине не удается сопоставить код FIPS, он ничего не возвращает для этой записи, поэтому вы не можете гарантировать соотношение ввода / вывода 1 к 1.
Использование известного дефекта подчеркивает это:
act_19 <- structure(list(GESTFIPS = c(40L, 99L), GTCO = c(0L, 153L), TUCASEID = c(2.02e 13, 2.02e 13), t150701 = c(60L, 40L), t150799 = c(0L, 0L), t150801 = c(0L, 0L), t150899 = c(0L, 0L), t159999 = c(0L, 260L)), class = "data.frame", row.names = c("1", "2"))
usmap::fips_info(act_19$GESTFIPS)
# Error in fips_info.numeric(act_19$GESTFIPS) :
# Invalid FIPS code(s), must be either 2 digit (states) or 5 digit (counties), but not both.
usmap::fips_info(as.character(act_19$GESTFIPS))
# Warning in get_fips_info(fips_) :
# FIPS code(s) 99 not found, excluded from result.
# abbr fips full
# 1 OK 40 Oklahoma
Я предлагаю альтернативный метод:
abbrs <- usmap::fips_info(as.character(unique(act_19$GESTFIPS)))
# Warning in get_fips_info(fips_) :
# FIPS code(s) 99 not found, excluded from result.
abbrs
# abbr fips full
# 1 OK 40 Oklahoma
abbrs %>%
transmute(state_abb = abbr, GESTFIPS = as.integer(fips)) %>%
right_join(act_19, by = "GESTFIPS")
state_abb GESTFIPS GTCO TUCASEID t150701 t150799 t150801 t150899 t159999
1 OK 40 0 2.02e 13 60 0 0 0 0
2 <NA> 99 153 2.02e 13 40 0 0 0 260
У вас все еще могут быть записи с неправильными state_abb
, но, по крайней мере, вы сохраните все свои предыдущие данные и не получите эту ошибку.
Комментарии:
1. Это будет . Например, попробуйте
act_19$state_abb <- usmap::fips_info(as.character(act_19$GESTFIPS))$abbr
использовать мои образцы данных. Он предупредит, но неправильно присвоит"OK"
обеим строкам. Это не ошибка, потому что здесь работает переработка. Любой код, который работает, когда работает переработка, обязательно содержит неверные данные. Попытка объединения (которая у вас также была) устранит эту проблему. Таким образом, хотя мои данные не показывают ошибку повторного использования, они показывают ту же проблему .2. Конечно, это первое сообщение об ошибке может не быть включено в исходную жалобу. Я сохранил его, чтобы продемонстрировать, почему я заставлял
as.character
иas.integer
.