Introducción
La mayoría de los datos que utilizamos en I+D proceden de bases de datos, archivos Excel o CSV, o se introducen directamente en JMP. Pero los datos de apoyo suelen venir en otros formatos, sobre todo en archivos PDF. Por ejemplo, pensemos en tablas de referencia de productos químicos, hojas de información de proveedores o incluso datos históricos de empresas que ahora solo existen en formato PDF. Este tipo de información de apoyo puede resultar muy útil para complementar los datos experimentales y, afortunadamente, JMP cuenta con un asistente de importación de PDF que permite importar este tipo de datos. Como estas tablas no estaban formateadas para software estadístico como JMP, la importación de datos desde archivos PDF suele dar lugar a tablas de datos desordenadas que, a veces, requieren pasos de limpieza adicionales.
En mi pasado en I+D, conocía el asistente de importación de PDF en JMP y lo utilizaba a veces. También hubo casos en los que encontré datos PDF para ampliar mi proyecto de investigación, pero no pude descubrir cómo limpiar la tabla después de importar los datos a JMP. En esos casos, tuve que abandonar el proyecto y prescindir de la información adicional, lo que fue muy frustrante.
Unos años después, siento que tengo las herramientas para trabajar con cualquier archivo PDF, sin importar lo desordenado que esté el dato después de la importación. Como ocurre con muchos problemas de datos desordenados, las fórmulas de columna son la mejor manera de limpiar los datos PDF importados. Esto es especialmente cierto cuando se registran los pasos en Workflow Builder o cuando se desea capturar el script para automatizar el proceso.
¿Quién debería leer este blog?
Sigue leyendo si:
- ¿Quiere aprender más sobre los conceptos básicos del asistente de importación de PDF?
- ¿Se queda atascado con la limpieza de datos después de importar datos PDF?
- ¿Quiere obtener más información sobre el uso de columnas de banderas y subíndices de columnas para limpiar datos?
- ¿Quieres aprender a repetir los pasos de limpieza del DPF en varias páginas?
Tenga en cuenta que no es necesario leerlo todo; puede saltar a la sección que le interese a continuación.
Descripción general
Al limpiar datos importados de archivos PDF, encuentro que recurro a dos construcciones, que utilizo solas o en combinaciones. Son:
- Columnas de indicadores: creación de un indicador binario para identificar filas que cumplen un determinado criterio. Puede ser “faltante o no faltante”, “cero” o “no cero”, etc. El uso de indicadores en columnas también se puede utilizar junto con la selección de filas en función de una condición.
- Subíndices de fila: compara una celda con la siguiente (o con la anterior) y utiliza esto para generar una columna de indicadores o para concatenar valores de celdas de celdas secuenciales. Utiliza Row(), Row() +1, Row()-1 como subíndice de columna (se utiliza entre corchetes de subíndice “[ ]”).
También tengo una serie de fórmulas útiles que uso a menudo.
Fórmulas útiles:
- Falta()
- Contiene()
- Si ()
- Longitud()
- Concatenar (“||”)
En esta publicación de blog, examinaré los siguientes tipos de problemas que suelen asociarse con la importación de datos PDF:
Para cada tema encontrarás una breve discusión y un vídeo.
Antes de analizar estos problemas y cómo solucionarlos, recuerde que en JMP casi siempre hay varias formas de llegar al mismo resultado final. Sin embargo, elegiré soluciones que estén registradas en Workflow Builder para que los pasos de limpieza se puedan repetir con un flujo de trabajo. Normalmente, esto significa que utilizaré columnas de fórmula en lugar de la opción de clic derecho "más rápida" (si está disponible) o utilizaré una opción de complemento. Configurar los pasos de limpieza de forma que cada paso se registre me permite utilizar el flujo de trabajo en otras tablas de datos que necesitan exactamente los mismos pasos de limpieza. Por ejemplo, consulte el ejemplo final de una tabla PDF que abarca 13 páginas. Al importar este PDF a JMP, se crean 13 tablas. Como puede ver en el último video, grabé los pasos de limpieza para la primera tabla con columnas de fórmula y luego hice un bucle de los pasos de limpieza en JMP para aplicarlos a las 13 tablas (lo hice con la función Agrupar con Para cada en Workflow Builder en JMP 18), lo que hace que limpiar las 13 tablas sea fácil. Vaya a los videos con ejemplos de bucles de Workflow Builder aquí .
Comencemos con un ejemplo sencillo. Si no está familiarizado con el asistente de importación de PDF en JMP, mire primero este video para ver cómo utilizo el asistente de importación para ingresar datos de este PDF en JMP.
Problema 1: Valores de celda faltantes debido al encabezado de fila fusionado en PDF.
A menudo, las tablas de los archivos PDF se formatean como si se hubieran fusionado varias filas y contienen un único valor, como un subtítulo. Al importarlas a JMP, la tabla tiene filas vacías en lugar de repetir el valor para cada fila que contiene datos (Figura 1).
Figure 1: Missing cell values in JMP (right side of image) due to merged row subheaders (left side of image).Figure 1: Missing cell values in JMP (right side of image) due to merged row subheaders (left side of image).Figure 1: Missing cell values in JMP (right side of image) due to merged row subheaders (left side of image).Figure 1: Missing cell values in JMP (right side of image) due to merged row subheaders (left side of image).Figura 1: Valores de celda faltantes en JMP (lado derecho de la imagen) debido a subencabezados de fila fusionados (lado izquierdo de la imagen).
Una posible solución rápida para la limpieza es seleccionar la columna con los valores faltantes (por ejemplo, Columna 3 en la Figura 1), luego hacer clic derecho en una celda y seleccionar Rellenar , seguido de Reemplazar faltante con valor anterior . En todas las versiones de JMP hasta JMP 18, esta acción de clic derecho aún no se registra en Workflow Builder o en el registro avanzado. Se agregará en JMP 19, pero para versiones anteriores, una opción más sólida para reemplazar valores de celda faltantes con el valor anterior que se registra en Workflow Builder o en el registro avanzado es usar una fórmula de columna. Utilicé una fórmula de columna que, en la fórmula misma, asigna una variable llamada "var" si no falta la Columna 3 y luego usa este valor para el siguiente valor faltante (Figura 2). Este método funciona bien para reemplazar valores anteriores, porque la fórmula de columna se ejecuta de arriba hacia abajo. En otras palabras, cada vez que hay un valor en la Columna 3, la variable "var" se actualiza y el valor actualizado se usa para las filas posteriores hasta que se produce una nueva actualización para una fila que no falta.
Figure 2: Replacing missing with previous value column formula.Figure 2: Replacing missing with previous value column formula.Figure 2: Replacing missing with previous value column formula.Figure 2: Replacing missing with previous value column formula. Figura 2: Fórmula para reemplazar la columna de valor faltante por la anterior.
Mírame demostrar este paso en el siguiente video:
Problema 2a: El valor de la celda se divide en varias filas
Otro ejemplo de filas fusionadas en una tabla PDF que requieren limpieza en JMP es cuando un valor, como un subencabezado, se divide en varias filas de una columna (Figura 3).
Figure 3: A cell value, in this case a category subheader (left), is split over multiple rows on import to JMP (right).Figure 3: A cell value, in this case a category subheader (left), is split over multiple rows on import to JMP (right).Figure 3: A cell value, in this case a category subheader (left), is split over multiple rows on import to JMP (right).Figure 3: A cell value, in this case a category subheader (left), is split over multiple rows on import to JMP (right).Figura 3: Un valor de celda, en este caso un subencabezado de categoría (izquierda), se divide en varias filas al importar a JMP (derecha).
Para solucionar este problema, es necesario identificar las partes de las cadenas y luego unirlas. Es necesario repetir toda la cadena para las filas correspondientes y luego eliminar las cadenas parciales restantes. Una forma de resolver este problema es crear una columna de indicadores que identifique los elementos faltantes y los que no faltan, o que identifique la “próxima fila faltante” y la “próxima fila no faltante”. Para el ejemplo de la Figura 3, la siguiente es una posible secuencia de pasos (todos los cuales se muestran en la Figura 4):
- Identifique las filas que tienen texto y las filas sin texto con una columna Bandera (Paso 1).
- Utilice la columna Bandera y una fórmula con subíndices de fila para identificar filas con texto y concatenar con texto en la siguiente fila (Paso 2).
- Una vez que haya celdas con la cadena completa, cree una columna de bandera para identificar las filas con cadenas de texto parciales y elimine estas cadenas parciales (Pasos 3 y 4).
Reemplace los valores faltantes de las celdas vacías con la cadena completa (ver solución para el problema 1).
En el ejemplo de la Figura 3, utilicé las fórmulas que se muestran en la Figura 4.
Figure 4: Series of column formulas to find and correct a subheader split over two rows.Figure 4: Series of column formulas to find and correct a subheader split over two rows.Figure 4: Series of column formulas to find and correct a subheader split over two rows.Figure 4: Series of column formulas to find and correct a subheader split over two rows.Figura 4: Serie de fórmulas de columnas para encontrar y corregir un subencabezado dividido en dos filas.
Puedes verme demostrar estos pasos aquí:
Problema 2b: El valor de la celda se divide en varias columnas
Para el siguiente ejemplo, utilizo un archivo PDF diferente, que encontré aquí . En este caso, los valores de las celdas se dividen en dos filas Y en dos columnas. Observa la imagen de la izquierda en la Figura 5. En este ejemplo, el nombre químico “Oxi-1,4-fenilensulfonil-1,4-fenilenoxi-1,4-fenelineisopropilideno-1,4-fenileno” (indicado por el recuadro azul) no solo se divide en dos filas sino también en dos columnas. Esto sucedió porque, más arriba en la tabla, se enumeran dos valores para la Tg de transición vítrea en lugar de uno, lo que hace imposible que un divisor de columnas evite cortar el nombre químico o los valores de Tg (ver el divisor de columna vertical rojo).
Figure 5: Thermal Transitions table demonstrating a cell value that is split over multiple columns and rows.Figure 5: Thermal Transitions table demonstrating a cell value that is split over multiple columns and rows.Figure 5: Thermal Transitions table demonstrating a cell value that is split over multiple columns and rows.Figure 5: Thermal Transitions table demonstrating a cell value that is split over multiple columns and rows.Figura 5: Tabla de transiciones térmicas que muestra un valor de celda dividido en varias columnas y filas.
(Fuente: https://www3.nd.edu/~hgao/thermal_transitions_of_homopolymers.pdf)
Cuando se coloca el divisor de columnas, como se muestra en la imagen izquierda de la Figura 5, hay dos celdas en la columna Tg que tienen texto de corte que pertenece a la columna Repeating Unit. En este caso, podemos aprovechar el hecho de que el texto de corte son letras, en lugar de los números que están en las otras celdas. Por lo tanto, una forma de corregir este problema es seguir estos pasos, como se muestra en la Figura 6:
- Crea una columna con el primer carácter (Paso 1).
- Utilice la opción Reemplazar cadena de la plataforma Recode para reemplazar cualquier cosa que sea un número por nada. Para ello, utilicé la expresión regular [0-9-] para encontrar todos los números, incluido el “-”. (Paso 2).
- Utilice la fórmula “Ismissing” para localizar la cadena de texto y concatenarla con la cadena original (cortada) (Paso 3).
- Limpia la columna Tg usando declaraciones condicionales y la columna Text Flag. Si bien este método es un poco complicado, cumple su función. Si conoces una expresión regular, también puedes usarla aquí en la opción de columna Recode. Utilicé las declaraciones condicionales que se muestran en la Figura 7.
Después de toda esta limpieza, identifiqué dónde se dividen verticalmente los contenidos de las celdas en dos filas: filas 39/40, 41/42 y 43/44. Las celdas que están divididas tienen la primera parte de la cadena terminada con un “-”, por lo que se puede usar como indicador. A continuación, se puede usar una construcción de fórmula como la que se muestra en la Figura 4 para sumar las cadenas de texto. Finalmente, se pueden eliminar las celdas de datos vacías para evitar filas duplicadas.
Figure 6: Finding and concatenating split text strings.Figure 6: Finding and concatenating split text strings.Figure 6: Finding and concatenating split text strings.Figure 6: Finding and concatenating split text strings.Figura 6: Búsqueda y concatenación de cadenas de texto divididas.
Figure 7: Removing text string from numbers column.Figure 7: Removing text string from numbers column.Figure 7: Removing text string from numbers column.Figure 7: Removing text string from numbers column.Figura 7: Eliminación de la cadena de texto de la columna de números.
El siguiente vídeo muestra cómo utilicé estos pasos para que puedas ver una posible solución para este problema.
Problema 3: Las filas con encabezados o subtítulos se mezclan con los datos
Para el último ejemplo, vuelvo al PDF que enumera las composiciones de ácidos grasos para las grasas. En este caso, puede ver que la tabla de datos contiene filas con encabezados, unidades o subencabezados que, al importarlos a JMP, ahora se mezclan con los datos (Figura 8).
Una forma de identificar dichas filas es utilizar la fórmula “Contiene” para identificar un símbolo o una cadena de texto en la fila de encabezado/unidad que no se encuentra en los datos reales. En la Figura 8, por ejemplo, utilizamos la fórmula “Contiene(“%”)”. Esta fórmula dará como resultado un “0” si este símbolo no aparece en la celda o en la ubicación real del carácter en la cadena (lo que dará como resultado un número entero > 0). Con una simple declaración condicional, se puede generar una columna Flag.
Para este ejemplo, se muestra una posible fórmula en la Figura 9. Para eliminar las filas con un “1” (que indica que el “%” está presente), seleccione las filas que cumplan con este criterio utilizando la opción “seleccionar dónde” del menú Fila/Selección de filas (Figura 10). A continuación, elimine las filas seleccionadas. El registro avanzado y el generador de flujo de trabajo capturan esta secuencia de pasos y pueden automatizarla para su uso repetido. Tenga en cuenta que hay un conjunto limitado de criterios de selección directamente disponibles en el menú “seleccionar dónde”, incluido “Contiene”, por lo que puede configurarlo directamente y omitir la columna Marcador.
Figure 8: Rows with headers or subheaders are mixed in with the data and appear as rows in the JMP table.Figure 8: Rows with headers or subheaders are mixed in with the data and appear as rows in the JMP table.Figure 8: Rows with headers or subheaders are mixed in with the data and appear as rows in the JMP table.Figure 8: Rows with headers or subheaders are mixed in with the data and appear as rows in the JMP table. Figura 8: Las filas con encabezados o subencabezados se mezclan con los datos y aparecen como filas en la tabla JMP.
Figure 9: Conditional statement with "Contains" formula to create a Flag column that identifies if the "%" character is present.Figure 9: Conditional statement with "Contains" formula to create a Flag column that identifies if the "%" character is present.Figure 9: Conditional statement with "Contains" formula to create a Flag column that identifies if the "%" character is present.Figure 9: Conditional statement with "Contains" formula to create a Flag column that identifies if the "%" character is present.Figura 9: Declaración condicional con la fórmula "Contiene" para crear una columna de bandera que identifica si el carácter "%" está presente.
Figure 10: Adding conditional row selection criteria using a Flag column.Figure 10: Adding conditional row selection criteria using a Flag column.Figure 10: Adding conditional row selection criteria using a Flag column.Figure 10: Adding conditional row selection criteria using a Flag column.Figura 10: Agregar criterios de selección de filas condicionales usando una columna de Bandera.
En este video, puede ver los pasos de limpieza utilizados para identificar y eliminar filas no deseadas en la tabla de datos (en este caso, las filas de subencabezado).
Vídeos adicionales: ejemplos de importación con el bucle WorkflowBuilder
En este video, observe cómo todos los pasos de limpieza realizados para la primera página se pueden aplicar a una segunda página con solo unos pocos clics. Utilizo el bucle "Agrupar con For Each" en Workflow Builder para el ejemplo fat.pdf que se muestra en la discusión anterior. A continuación, demuestro un caso más extremo en el que tengo 13 páginas en un formato de tabla ancha. Cada página debe importarse por separado y debe limpiarse. Sin embargo, una vez que utilicé el asistente de importación de PDF para importar la tabla desde cada página, simplemente puedo registrar los pasos de limpieza para una tabla. Luego, puedo usar la opción "Agrupar con For Each" en Workflow Builder para ejecutar automáticamente los pasos de limpieza en las otras 12. ¡¿Qué tan eficiente es eso?!
Por último, estoy 100% seguro de que existen formas más breves o más claras de abordar algunos de estos problemas que aún no conozco. No dudes en compartir otras soluciones en los comentarios a continuación.