Análisis de datos PISA. Obtención de muestras
En este post encontrarás ejemplos de código R para obtener muestras de la base de datos de PISA. En estos ejemplos se corrigen los diferentes pesos de los alumnos, escuelas o padres en función del número de registros seleccionados para la muestra. También se realizan muestreos estratificados por los valores de una determinada columna del conjunto de datos.
Las muestras se realizan a partir de un dataframe que contiene el conjunto completo de datos, el cual se construye a partir de los datos extraídos por la aplicación WinPODUtil.
Este post está relacionado con el artículo introducción al análisis de datos PISA.
En este enlace podéis descargar el código R con los ejemplos. Se trata de tres pequeñas funciones, una para realizar un muestreo simple, y otras dos para realizar un muestreo estratificado por una de las columnas de la muestra, que generalmente será el país al que pertenecen los alumnos.
En este enlace podéis descargar el programa R para Windows.
Ejemplo 1, realizar un muestreo simple corrigiendo los pesos
En este ejemplo obtendremos una muestra de n filas seleccionando algunas columnas del conjunto de datos completo y corrigiendo los pesos para ajustarlos al tamaño de la submuestra. La idea es que la suma de los pesos siempre nos dé el tamaño aproximado de la población total de la que procede la muestra, de manera que debemos multiplicar el valor por el tamaño de la muestra completa y dividirlo por el tamaño de la submuestra.
wght_sample <- function(data,fields,nmax,wghts,naomit = T) {
if (naomit) {
rdata<-na.omit(data[,fields]);
}
else {
rdata<-data[,fields];
}
if (nmax > nrow(rdata)) {
nsamp<-nrow(rdata);
}
else {
nsamp<-nmax;
}
rdata<-rdata[sample(nrow(rdata),nsamp),];
if (!is.null(wghts)) {
if (is.numeric(wghts[0])) {
rdata[,names(data)[wghts]] <- rdata[,names(data)[wghts]] *
length(data[,1]) / length(rdata[,1]);
}
else {
rdata[,wghts] <- rdata[,wghts] * length(data[,1]) /
length(rdata[,1]);
}
}
return(rdata);
}
En el parámetro data le pasaremos el dataframe con el conjunto de datos completo. En fields pasaremos una lista de las columnas que queremos conservar en la muestra final, que puede ser una lista de nombres de campos o de índices. El parámetro nmax indica el tamaño máximo de la muestra a obtener y wghts contiene la lista de columnas que contienen pesos y hay que corregir en la muestra. Esta lista se puede construir también con los nombres o con los índices de las columnas.
En el parámetro naomit podemos indicar si queremos eliminar las filas con valores faltantes. Por defecto estas filas se eliminarán de la muestra final.
El resultado de la función será un dataframe con las columnas seleccionadas y los pesos actualizados según el tamaño de la muestra.
Ejemplo 2, muestreo estratificado por uno de los campos
En este segundo ejemplo volvemos a realizar un muestreo con corrección de pesos, pero esta vez utilizando una de las columnas del dataframe como índice para realizar un muestreo estratificado. Esta columna debe contener datos de tipo factor.
Normalmente, esta columna será el país, en conjuntos de datos que contengan varios países, de manera que extraigamos un número de registros más o menos igual para cada uno de los países de la muestra, pero puede usarse con cualquier otra columna que sea de tipo factor.
El nombre de la función es wgtht_multiple_sample y este es el código:
wght_multiple_sample <- function(data,cnt,fields,nmax,wghts,naomit = T) {
lindex<-levels(data[,cnt]);
if (naomit) {
rdata<-na.omit(data[,c(cnt,fields)]);
}
else {
rdata<-data[,c(cnt,fields)];
}
rsamp<-subset(rdata,is.na(index));
for (i in 1:length(lindex)) {
total<-length(data[data[,index]==lindex[i],1]);
subs<-subset(rdata,rdata[,1]==lindex[i]);
if (nmax > nrow(subs)) {
nsamp<-nrow(subs);
}
else {
nsamp<-nmax;
}
isamp<-subs[sample(nrow(subs),nsamp),];
if (!is.null(wghts)) {
if (is.numeric(wghts[0])) {
isamp[,names(data)[wghts]] <- isamp[,names(data)[wghts]] *
total / length(isamp[,1]);
}
else {
isamp[,wghts] <- isamp[,wghts] * total / length(isamp[,1]);
}
}
rsamp<-rbind(rsamp,isamp);
}
return(rsamp);
}
En esta función tenemos los mismos parámetros que en la anterior, con el mismo uso y significado, y se ha añadido el parámetro cnt donde se pasa el nombre o índice de la columna que contiene los valores mediante los cuales queremos estratificar la muestra.
El resultado será un dataframe con las columnas seleccionadas, más la columna de estratificación, con un número aproximadamente igual de registros para cada uno de los valores de dicha columna.
Ejemplo 3, muestreo estratificado para uno solo de los valores
En este último ejemplo, veremos una función que realiza el mismo muestreo estratificado que el ejemplo anterior, pero devuelve solo datos para uno de los valores de la columna de estratificación. Por ejemplo sirve para extraer datos de un solo país de una muestra con varios países.
La función se llama wght_cnt_sample y este es su código:
wght_cnt_sample <- function(data,cnt,cntval,fields,nmax,wghts,naomit = T) {
if (naomit) {
rdata<-na.omit(data[,c(cnt,fields)]);
}
else {
rdata<-data[,c(cnt,fields)];
}
rsamp<-subset(rdata,is.na(cnt));
subs<-subset(rdata,rdata[,cnt]==cntval);
if (nmax > nrow(subs)) {
nmax <- nrow(subs);
}
rsamp<-subs[sample(nrow(subs),nmax),];
if (!is.null(wghts)) {
if (is.numeric(wghts[0])) {
rsamp[,names(data)[wghts]] <- rsamp[,names(data)[wghts]] *
length(data[,1]) / length(rsamp[,1]);
}
else {
rsamp[,wghts] <- rsamp[,wghts] * length(data[,1]) /
length(rsamp[,1]);
}
}
return(rsamp);
}
De nuevo hemos añadido un parámetro, cntval, donde se pasa el valor que debe tener la columna indicada en el parámetro cnt para que los registros sean seleccionados para la muestra.