JSL para generar la diferencia y el promedio de columnas coincidentesHola,
Espero obtener ayuda sobre lo siguiente:
Adjunto archivo JMP con la siguiente tabla.

Mi conjunto de datos típico/inicial contiene:
1. un identificador "Tipo"
2. un conjunto de un número desconocido de columnas con el mismo prefijo y varios sufijos numéricos, por ejemplo Un número1, Un número2, Un número3...
3. un segundo conjunto del mismo número de columnas que en el punto 2 anterior, con el mismo prefijo y sufijo coincidente que en el punto 2, por ejemplo, B num1, B num2, B num3...
¿Puedo obtener ayuda para escribir un script jsl para generar las columnas para emparejar las columnas del conjunto A y del conjunto B para calcular:
Fórmula( (:B 1.0 - :B 0.5) / (:A 1.0 - :A 0.5) ) ),
Fórmula( (:B 1.3 - :B 0.5) / (:A 1.3 - :A 0.5) ) ),
Fórmula( (:B 1.3 - :B 1.0) / (:A 1.3 - :A 1.0) ) ),
Luego, genere una columna Promedio ("B/A Promedio") para tomar la media de todas las columnas creadas. Tenga en cuenta que las columnas generadas arriba pueden ser cualquier número. Podrían ser 3, 2, 6...
Al final del día, lo que más me interesa es obtener la columna final de "Promedio B/A", las columnas intermedias son opcionales si eso simplifica el script.
Avíseme si puedo aclarar algo en mis preguntas. Muchas gracias por adelantado.
Automatización y secuencias de comandosAnálisis y modelado de datos básicosRe: JSL para generar diferencia y promedio de columnas coincidentes¿Qué determina los pares de columnas utilizadas para el cálculo?
Re: JSL para generar diferencia y promedio de columnas coincidentesTener el mismo sufijo (número). Por ejemplo, 0,5 a 0,5, 1,0 a 1,0, 1,3 a 1,3, etc...
Re: JSL para generar diferencia y promedio de columnas coincidentesSi tengo las columnas A0.5, A1.0, A1.3, B0.5, B1.0 y B1.3, ¿cómo sabría que necesito exactamente (B1.0-B0.5)/(A1.0- A0.5), (B1.3-B0.5)/(A1.3-A0.5) y (B1.3-B1.0)/(A1.3-A1.0) columnas?
Re: JSL para generar diferencia y promedio de columnas coincidentesMuchas gracias por trabajar pacientemente conmigo y me disculpo por no tener 100% clara la intención.
Para la ecuación, siempre será: ( B num1 - B num2 ) / ( A num1 - A num2 )
Dado que siempre obtendremos el mismo conjunto de sufijos entre el grupo A y el grupo B, mi objetivo es obtener todas las combinaciones posibles entre el grupo A, que pueden limitarse solo a sufijos de mayor valor y sufijos de menor valor.
Alternativamente, si simplifica el guión, podemos encontrar la diferencia entre cualquier par, digamos incluyendo ambos (B1.0-B0.5)/(A1.0-A0.5) y (B0.5-B1.0)/(A0.5-A1.0). De esta manera, el promedio seguirá siendo el mismo que el de mayor-menor.
Re: JSL para generar diferencia y promedio de columnas coincidentesAquí está mi método que crea las nuevas columnas que desea.
names default to here(1);
dt=current data table();
// Set Prefixes
pre1 = "A";
pre2 = "B";
// Get all levels using Pre1 columns to find the levels
theColumnNames = dt << get column names( string, continuous );
levels = {};
For Each( {col, i}, theColumnNames,
if(word(1,col," ")==pre1,
insert into(levels,trim(substr(col,length(pre1)+1)))
)
);
// Create new columns.
// This is accomplished by creating a character string that is the JSL statement that
// is required to create the new column and it's formula
meanColsList = {};
For( i = 2, i <= N Items( levels ), i++,
For( k = 1, k <= i - 1, k++,
Eval(
Parse(
"dt << New Column( \!"" || pre2 || "/" || pre1 || " " || levels[i] || "-" || levels[k] ||
"\!", formula( (:" || pre2 || " " || levels[i] || " - :" || pre2 || " " || levels[k] || ")
/ (:" || pre1 || " " || levels[i] || " - :" || pre1 || " " || levels[k] || ") ) );"
)
);
insert into( meanColsList, ":\!"" || pre2 || "/" || pre1 || " " || levels[i] || "-" || levels[k] || "\!"n");
);
);
Eval(
Parse(
"dt << New Column( \!"" || pre2 || "/" || pre1 || " Avg\!", formula( Sum(" ||
Concat Items( meanColsList, "," ) || ") / Number(" ||
Concat Items( meanColsList, "," ) || ")));"
)
);Re: JSL para generar diferencia y promedio de columnas coincidentesEsto también puede dar algunas ideas.
Names Default To Here(1);
dt = Open("$DOWNLOADS/Question - Auto Col Diff and Avg.jmp");
dt << Clear Column Selection << Clear Select;
col_list = dt << Get Column Names("String");
// Get column types
col_rgx_pattern = "^(.?) (\d+.\d+)";
aa = Associative Array();
For Each({col_name}, col_list,
rgx_result = Regex(col_name, col_rgx_pattern);
If(!IsMissing(rgx_result),
parts = Words(rgx_result);
If(N Items(parts) == 2,
If(!Contains(aa, parts[1]),
aa[parts[1]] = {};
);
Insert Into(aa[parts[1]], parts[2]);
);
);
);
// Check that all different columns have same number parts (ignored in this case)
// Create combinations
ordered_num_parts = Reverse(Sort List(aa[aa << first])); // sort from largest to smallest, works in this simple case
pairs = {};
For(i = 1, i <= N Items(ordered_num_parts) - 1, i++,
For(j = i + 1, j <= N Items(ordered_num_parts), j++,
cur_pair = Eval List({ordered_num_parts[i], ordered_num_parts[j]});
Insert Into(pairs, Eval List({cur_pair}));
);
);
// Create new columns
avg_expr = Expr(Mean());
For Each({pair}, pairs,
f_expr = Substitute(
Expr(
(_last_numerator_ - _first_numerator_) / (_last_denominator_ - _first_denominator_)
),
Expr(_last_numerator_), Name Expr(AsColumn(dt, "B " || pair[1])),
Expr(_first_numerator_), Name Expr(AsColumn(dt, "B " || pair[2])),
Expr(_last_denominator_), Name Expr(AsColumn(dt, "A " || pair[1])),
Expr(_first_denominator_), Name Expr(AsColumn(dt, "A " || pair[2]))
);
Eval(EvalExpr(new_col = dt << New Column("B/A " || pair[1] || "-" || pair[2], Numeric, Continuous, Formula(
Expr(Name Expr(f_expr))
))));
Insert Into(avg_expr, Name Expr(AsColumn((new_col << get name))));
);
Eval(EvalExpr(
dt << New Column("B/A AVG", Numeric, Continuous, Formula(
Expr(Name Expr(avg_expr))
));
));Re: JSL para generar diferencia y promedio de columnas coincidentesMuchas gracias Jarmo. Aprendí muchas formas nuevas de crear secuencias de comandos con este ejemplo. Aprecio tu ayuda.
Re: JSL para generar diferencia y promedio de columnas coincidentesMuchas gracias Jim por tu ayuda. Muy sencillo y fácil de entender. ¡Lo aprecio!