Haga más con R: tablas de búsqueda rápida usando vectores con nombre

¿Cuál es la abreviatura estatal de Arkansas? ¿Es AR? ¿ALASKA? ¿COMO?

Quizás tengas un marco de datos con la información. O cualquier información donde haya una columna con categorías y otra columna con valores. Lo más probable es que, en algún momento, desee buscar el valor por categoría, a veces conocido como clave . Muchos lenguajes de programación tienen formas de trabajar con pares clave-valor. Esto también es fácil de hacer en R con vectores con nombre. Así es cómo.

Tengo datos con nombres de estado y abreviaturas, que he almacenado en un marco de datos llamado postal_df. (El código para crear ese marco de datos se encuentra en la parte inferior de esta publicación si desea seguir adelante).

Correré tail(postal_df)para ver cómo se ve.

 Código postal del estado 45 Vermont VT 46 Virginia VA 47 Washington WA 48 West Virginia WV 49 Wisconsin WI 50 Wyoming WY

Una tabla de búsqueda / vector con nombre tiene valores como vector y claves como nombres. Permítanme primero hacer un vector de los valores, que están en la columna PostalCode:

getpostalcode <- postal_df $ PostalCode

Y luego agrego nombres de la columna Estado.

nombres (getpostalcode) <- postal_df $ Estado

Para usar este vector con nombre como tabla de búsqueda, el formato es mylookupvector ['clave'].

Entonces, aquí le mostramos cómo obtener el código postal de Arkansas:

getpostalcode ['Arkansas'] 

Si desea solo el valor, sin la clave, agregue la unnamefunción a ese valor que obtiene:

anular el nombre (getpostalcode ['Arkansas'])

Actualización: también puede obtener solo un valor usando el formato getpostalcode[['Arkansas']], es decir, corchetes dobles en lugar de agregar unname(). Gracias a Peter Harrison por el consejo a través de Twitter. Sin embargo, Hadley Wickham señala que el formato de doble corchete solo funciona para un valor. Si está haciendo algo como crear una nueva columna en un marco de datos, limítese a unname ().

Eso es todo al respecto. Sé que este es un ejemplo algo trivial, pero tiene algún uso en el mundo real. Por ejemplo, tengo un vector con nombre de códigos FIPS que necesito cuando trabajo con datos del censo de EE. UU.

Comencé con un marco de datos de estados y códigos FIPS llamados fipsdf(el código para eso está a continuación). A continuación, creé un vector llamado getfipsdesde la columna de código fips del marco de datos y agregué los estados como nombres.

fipsdf <- rio :: import ("datos / FIPS.csv")

getfips <- fipsdf $ FIPS

nombres (getfips) <- fipsdf $ Estado

Ahora, si quiero el código FIPS para Massachusetts, puedo usar getfips['Massachusetts']. Yo añadiría unname () para obtener sólo el valor sin el nombre de: unname(getfips['Massachusetts']).

Si tener que seguir usando se unname()vuelve demasiado molesto, incluso puede hacer una pequeña función desde su tabla de búsqueda:

get_state_fips <- función (estado, lookupvector = getfips) {

fipscode <- unname (lookupvector [estado])

retorno (fipscode)

}

Aquí, tengo dos argumentos para mi función. Uno es mi "clave", en este caso el nombre del estado; el otro es lookupvector, que por defecto es mi getfipsvector. 

Y puedes ver cómo uso la función. Es sólo el nombre de función con un argumento, el nombre del estado: get_state_fips("New York").

Puedo hacer una función que parezca un poco más genérica, como

get_value <- function (mykey, mylookupvector) {

myvalue <- mylookupvector [mykey]

myvalue <- unname (myvalue)

retorno (myvalue)

}

Tiene un nombre más genérico para la función get_value(); un primer nombre de argumento más genérico mykey, y un segundo argumento de mylookupvectoreso no tiene nada predeterminado.

Es lo mismo que he estado haciendo todo el tiempo: obtener el valor del vector de búsqueda lookupvector['key']y luego ejecutar la unname()función. Pero todo está envuelto dentro de una función. Entonces, llamarlo es un poco más elegante.

Puedo usar esa función con cualquier vector con nombre que haya creado. Aquí, lo estoy usando con Arkansas y mi getpostalcodevectorial:  get_value("Arkansas", getpostalcode).

¡Búsquedas fáciles en R! Recuerde que los nombres deben ser únicos. Puede repetir valores , pero no claves .

Vi esta idea por primera vez hace años en el libro Advanced R de Hadley Wickham . Todavía lo uso mucho y espero que también te resulte útil.

Código para crear marco de datos con abreviaturas postales

postal_df <- data.frame (stringsAsFactors = FALSE,

Estado = c ("Alabama", "Alaska", "Arizona", "Arkansas", "California",

"Colorado", "Connecticut", "Delaware", "Florida", "Georgia",

"Hawái", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas",

"Kentucky", "Luisiana", "Maine", "Maryland", "Massachusetts",

"Michigan", "Minnesota", "Mississippi", "Missouri", "Montana",

"Nebraska", "Nevada", "New Hampshire", "Nueva Jersey", "Nuevo México",

"Nueva York", "Carolina del Norte", "Dakota del Norte", "Ohio",

"Oklahoma", "Oregón", "Pensilvania", "Rhode Island", "Carolina del Sur",

"Dakota del Sur", "Tennessee", "Texas", "Utah", "Vermont",

"Virginia", "Washington", "Virginia Occidental", "Wisconsin", "Wyoming"),

PostalCode = c ("AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "FL", "GA",

"HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MD",

"MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ",

"NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA", "RI", "SC", "SD",

"TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI", "WY")

)

Código para crear marco de datos con códigos FIPS

fipsdf <- data.frame (State = c ("Alabama", "Alaska", "Arizona", "Arkansas",

"California", "Colorado", "Connecticut", "Delaware", "Florida",

"Georgia", "Hawái", "Idaho", "Illinois", "Indiana", "Iowa",

"Kansas", "Kentucky", "Luisiana", "Maine", "Maryland", "Massachusetts",

"Michigan", "Minnesota", "Mississippi", "Missouri", "Montana",

"Nebraska", "Nevada", "New Hampshire", "Nueva Jersey", "Nuevo México",

"Nueva York", "Carolina del Norte", "Dakota del Norte", "Ohio", "Oklahoma",

"Oregón", "Pensilvania", "Rhode Island", "Carolina del Sur", "Dakota del Sur",

"Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington",

"Virginia Occidental", "Wisconsin", "Wyoming"), FIPS = c ("01", "02",

"04", "05", "06", "08", "09", "10", "12", "13", "15", "16", "17",

"18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28",

"29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39",

"40", "41", "42", "44", "45", "46", "47", "48", "49", "50", "51",

"53", "54", "55", "56"), stringsAsFactors = FALSE)