rapplyspotfiresubscriptterr

Trouble with Spotfire R code (TERR) - Invalid subscript type 'list' error


I've written code that runs perfectly in R Studio (3.4.3). I copied the code over into a Spotfire project (TERR) and it ran fine once or twice, but now bombs with the "Invalid subscript type 'list'" error. I have identified it coming from the line below in the apply function.

minGT <- as.numeric(rownames(resultGT)[apply(resultGT , 2, which.min)])

I've spent several days trying potential solutions found on SO and other places to no avail. Below is some of the code block, reduced for perusing:

###Code revised previously after SO (@Parfait) assistance - different problem##
library(plyr)

DS <- DirectionalSurveys[, c("IDWELL", "API", "WELL NAME", "DIVISON", "MD", "INCL", "AZIM", "NS", "EW", "TVD", "DLS", "Northing", "Easting")]
Perf <- Perforation[, c("IDWELL", "Well API Number", "Well Name", "County", "Mid Perf MD", "Mid Perf TVD")]
colnames(DS) <- c("IDWELL", "API", "WellName", "Division", "MD", "INCL", "AZIM", "NS", "EW", "TVD", "DLS", "Northing", "Easting")
colnames(Perf) <- c("IDWELL", "API", "WellName", "County", "MidPerfMD", "MidPerfTVD")

df_lists <- lapply(seq_along(WellName), function(i) {

    S <- DS$MD[DS$WellName == WellName[i]]
    P <- Perf$MidPerfMD[Perf$WellName == WellName[i]]

    resultGT <- outer(S, P, '>=')
    resultGT[resultGT == FALSE] <- 50
    rownames(resultGT) <- paste0(S)
    colnames(resultGT) <- paste0(P)

#This is the line that throws the error - specifically the `apply` function

    minGT <- as.numeric(rownames(resultGT))[apply(resultGT , 2, which.min)]

#Calculations begin below after some additional subsetting (not shown)
    deep <- S[match(minGT, S)]
    shallow <- S[match(minGT, S) - 1]
#............etc.
#Remainder of code removed to prevent recipient boredom....

I'd really appreciate some (more) help - @Parfait has already helped me get the entire code running previously, so thanks in advance for any additional assistance. I can provide a data set and full coding as necessary.

Here is the error message in its entirety: Error message generated


Solution

  • I was able to obtain a solution to my problem with the help of DougJ at the Tibco Community website. Below is a test set that DougJ performed to identify the source of the problem was from the data.frame(P) which contained empty cells - note that data.frame(P) consists of roughly 120 rows per iteration while data.frame(S) has over 300 rows per iteration. My solution to the difference in dataframe sizes was the statement resultGT <- outer(S, P, ">=") with a subsequent statement minGT <- rownames(resultGT)[apply(resultGT, 2, which.min)] to find minimum values of "S" for each individual value of "P". This worked flawlessly in RStudio, but threw the error in Spotfire with TERR.

    #Test case below as performed by DougJ (Tibco Community) that identified problem area.
    > xNA <- c(1:2, NA, 3:4)
    > yNA <- c(3:5, NA, 6)
    > 
    > xNA
    [1]  1  2 NA  3  4
    > 
    > yNA
    [1]  3  4  5 NA  6
    > 
    > resultGT <- outer( xNA, yNA, ">=" )
    > 
    > resultGT[resultGT == FALSE] <- 50
    > 
    > rownames( resultGT ) <- paste0(xNA)
    > colnames( resultGT ) <- paste0(yNA)
    > 
    > resultGT
      3  4  5 NA  6
    1  50 50 50 NA 50
    2  50 50 50 NA 50
    NA NA NA NA NA NA
    3   1 50 50 NA 50
    4   1  1 50 NA 50
    > 
    > 
    > apply(resultGT, 2, which.min)
    $`3`
    3 
    4 
    
    $`4`
    4 
    5 
    
    $`5`
    1 
    1 
    
    $`NA`
    integer(0)
    
    $`6`
    1 
    1 
    
    > class( apply(resultGT, 2, which.min) )
    [1] "list"
    > 
    > 
    > as.numeric(rownames(resultGT))
    [1]  1  2 NA  3  4
    Warning message:
    NAs introduced by coercion 
    > 
    > as.numeric(rownames(resultGT))[ apply(resultGT, 2, which.min) ]
    Error in as.numeric(rownames(resultGT))[apply(resultGT, 2, which.min)] : 
      invalid subscript type 'list'
    In addition: Warning message:
    NAs introduced by coercion 
    > 
    

    Below is the final code that was developed by DougJ as the solution:

    #original code:
    minGT <- rownames(resultGT)[apply(resultGT , 2, which.min)]
    
    #new code (with slight modification):
    minGT <- rownames(resultGT)[apply(resultGT, 2, function(X) {tmp <- which.min(X); ifelse(length(tmp), tmp, NA)} )]
    

    Now works in Spotfire with TERR. Thanks to DougJ if you're on SO!