Recupero dell'elenco di elenchi annidati da R a JMPCiao a tutti,
Sto tracciando le informazioni da un'API usando R e recuperando le informazioni in JMP. Ho avuto successo con il recupero dei dati fino a quando l'API non restituisce un elenco annidato di elenchi.
Sto pensando che l'errore non viene richiesto dal lato R perché, sono in grado di eseguire lo stesso pezzo di codice in R Studio senza errori. Anche in JSL, l'errore si verifica solo quando sto cercando di recuperare l'oggetto da R a JMP usando R Get (). Ottengo l'errore mostrato di seguito quando provo:
R Get(A) ;
R Get () supporta il recupero delle liste - c'è qualcosa che sto facendo male?

Inoltre, dal momento che ho elenchi di elenchi annidati, mi chiedo se il looping dei contenuti dell'elenco sia il modo più efficace per estrarre i dati?
Ri: Recupero Elenco di elenchi annidati da R a JMPQuesto è più complesso. In R, tutti gli argomenti vengono passati per valore, quindi anche nella prima chiamata la modifica di "l" ne crea effettivamente una copia all'interno del namespace della funzione e l'elenco che si sta tentando di modificare non è stato modificato. Nelle chiamate successive stai operando su versioni più piccole di "l" che, ancora una volta, non fanno riferimento al tuo elenco attuale. Per correggere l'elenco è necessario salvare un riferimento nello spazio dei nomi in cui risiede l'elenco e quindi utilizzare l'argomento loc per capire quale parte lanciare, o creare una nuova copia dell'elenco e restituirla. Faccio quest'ultimo qui:
#verbose levels
# 0 nothing
# 1 Errors only
# 2 Everything
isvalid <- function(l, fix=FALSE, verbose = 2, loc = {} ) {
if(length(loc) > 10) throw("List is too deep, maybe you have raw data?")
for( i in seq_along(l) ) {
if( class(l[[i]]) == "list" ) {
#If a list, check recurse through it, fixing errors along the way if necessary
if (verbose > 1) print(paste0("Found list at: ", paste(c(loc, i), collapse = ", ")))
l[[i]] <- isvalid(l[[i]], fix=fix, verbose=verbose, loc=c(loc, i))
} else if (!(class(l[[i]]) %in% c("numeric", "character", "NULL"))) {
#If not valid data, try to cast as a list, or throw an error
if (verbose > 0) print(paste0("Invalid data (", class(l[[i]]), ") found at: ", paste(c(loc, i), collapse = ", ")))
if( fix ) {
#Cast as a list
l[[i]] <- as.list(l[[i]])
#Make sure it worked
if( class(l[[i]]) == "list" ) {
#If it is a list, recurse through it
if (verbose > 0) print(paste0("Successfully cast data as a list at: ", paste(c(loc, i), collapse = ", ")))
l[[i]] <- isvalid(l[[i]], fix=fix, verbose=verbose, loc=c(loc, i))
} else {
#Throw a message if failed, not sure what might cause this
errmsg <= paste0("Failed to cast '", class(l[[i]]), "' as a list at: ", paste(c(loc, i), collapse = ", "))
throw( errmsg )
}
}
} else {
#Found valid data
if (verbose > 1) print(paste0("Found ", class(l[[i]]), " at: ", paste(c(loc, i), collapse = ", ")))
}
}
#Return this part of the list unless not fixing anything and this is the first call
return(if((!fix) & (length(loc) == 0)) {invisible()} else {l} )
}
#A list with a problem
lst <- list(list("a", "b",data.frame(a=c(1,2))), 2)
#Look for problems
isvalid(lst, verbose = 1)
#Fix problems
lst <- isvalid(lst, fix=TRUE, verbose = 1)
#Show the new data structure
isvalid(lst, verbose = 2)
Si noti che ho provato a includere i dati binari non elaborati all'interno della lista e si è ripetuto fino a quando non ho ricevuto un errore di overflow. Se ci si imbatte in questo, potrebbe essere necessario fare qualcos'altro.
Ri: Recupero Elenco di elenchi annidati da R a JMP @ih ,
Questo ci sta guidando nella giusta direzione, se non mi sento avido, mi piacerebbe avventurarmi e fare un'altra domanda.
isvalid <- function(l, loc = {} )
{
for( i in seq_along(l) )
{
if( class(l[[i]]) == "list" )
{
isvalid(l[[i]], c(loc, i))
} else if (!(class(l[[i]]) %in% c("numeric", "character")))
{
l[i] <- as.list(l[i])
#print(paste0("Invalid data found at: ", paste(c(loc, i), collapse = ", ")))
} else
{
#print(paste0("Valid data found at: ", paste(c(loc, i), collapse = ", ")))
}
}
}
isvalid(DesResult)Ho aggiunto una riga per fondere fondamentalmente i dati non validi trovati in una lista - sperando che questo risolvesse il problema. Tuttavia, non penso che abbia funzionato come mi aspettavo. Qualche idea su come risolverlo?
Ri: Recupero Elenco di elenchi annidati da R a JMPRicevo spesso strani errori durante il tentativo di importare tipi di dati non validi. Potresti provare a controllare ogni elemento del tuo elenco per assicurarti che sia un elenco, un numero o una stringa. Ecco un modo per farlo (non completamente testato):
isvalid <- function(l, loc = {} ) {
for( i in seq_along(l) ) {
if( class(l[[i]]) == "list" ) {
isvalid(l[[i]], c(loc, i))
} else if (!(class(l[[i]]) %in% c("numeric", "character"))) {
print(paste0("Invalid data found at: ", paste(c(loc, i), collapse = ", ")))
} else {
#print(paste0("Valid data found at: ", paste(c(loc, i), collapse = ", ")))
}
}
}
lst = list(list("a", "b",data.frame(a=c(1,2))), 2)
isvalid(lst)Che restituisce:
> lst = list(list("a", "b",data.frame(a=c(1,2))), 2)
> isvalid(lst)
[1] "Invalid data found at: 1, 3"Ri: Recupero Elenco di elenchi annidati da R a JMP @ih ,
Nel mio caso, non sto provando a iscrivermi agli elenchi. Ho provato il tuo esempio e funziona perfettamente, tuttavia, quando provo la stessa identica cosa sulla mia estremità, non capisco perché sto fallendo.
Ho controllato se i dati sono archiviati come elenco in R e in effetti è un elenco.

In JMP, ecco cosa faccio:
DesResult = R Get("DesResult"); Dà ancora lo stesso errore, ma questo non ha senso perché il tuo esempio dimostra chiaramente che dovrebbe essere recuperabile
Ri: Recupero Elenco di elenchi annidati da R a JMPR Get recupererà le liste annidate da R. Devi ottenere l'intera lista (non credo che tu possa iscriverti nel comando R Get) e combatta con i frame di dati contenenti liste, o qualsiasi cosa diversa da numeri e caratteri.
Names default to here( 1 );
R Init();
R Submit( "\[
a <- list( 1, 2, list("a", list( "b", "c" ) ) )
]\");
a = R Get( "a" );
Show( a[3][2][1] );
R Term();