wmay / dwnominate

An R interface to the DW-NOMINATE roll call scaling program
https://wmay.github.io/dwnominate
Other
22 stars 4 forks source link

Error: NAs in foreign function call (arg 14) #15

Closed knutwannheden closed 3 years ago

knutwannheden commented 3 years ago

I have installed the latest dwnominate from GitHub. When I run my code (under Linux) I get the following runtime error:

> res <- dwnominate::dwnominate(l, id="ID", dims=1)
Calculating W-NOMINATE scores for each session...
Extracting common space scores...
Running DW-NOMINATE...
Error in dwnominate::dwnominate(l, id = "ID", dims = 1) :
  NAs in foreign function call (arg 14)
In addition: There were 16 warnings (use warnings() to see them)

Here are the warnings:

> warnings()
Warning messages:
1: In max(distances, na.rm = T) : no non-missing arguments to max; returning -Inf
2: Unknown or uninitialised column: `icpsrState`.
3: Unknown or uninitialised column: `cd`.
4: Unknown or uninitialised column: `icpsrState`.
5: Unknown or uninitialised column: `cd`.
6: Unknown or uninitialised column: `icpsrState`.
7: Unknown or uninitialised column: `cd`.
8: Unknown or uninitialised column: `icpsrState`.
9: Unknown or uninitialised column: `cd`.
10: Unknown or uninitialised column: `state`.
11: Unknown or uninitialised column: `icpsrState`.
12: Unknown or uninitialised column: `cd`.
13: Unknown or uninitialised column: `state`.
14: Unknown or uninitialised column: `icpsrState`.
15: Unknown or uninitialised column: `cd`.
16: Unknown or uninitialised column: `state`.

Here some observations:

  1. ~The same code works fine with older versions of dwnominate (I will try to pin down exactly which commit started causing this problem).~
  2. I can run the same version of dwnominate just fine against the nhsenate test data.
wmay commented 3 years ago

This seems to suggest something is wrong with the legislator ID values. Could some of them be NA? If you can find the specific commit where it breaks, that would definitely be helpful.

knutwannheden commented 3 years ago

No, that isn't really possible. I have however made another very strange observation: If I restart the interactive R after the calculation fails (while saving my workspace) and then retry the same dwnominate call again, then it works. This is all very mysterious...

wmay commented 3 years ago

I'm pretty baffled by that, so I need more info to figure this out. What was the old version you tried? If you can make a reproducible example-- maybe you can make the error occur with only a small subset of your data-- that would be really helpful.

knutwannheden commented 3 years ago

Actually it seems like I have the same problem with older versions of dwnominate. So far the only workaround I have found is to restart R, which seems very weird.

knutwannheden commented 3 years ago

OK, I will try to narrow the problem down. Just in case you have any more ideas, I read my data into R from a relational database and then create the rollcall objects like this for the sessions:

l <- list()
for (i in unique(v$Session)) {
  session_v <- filter(v, Session == i)
  # Wide Form
  session_v_pivot <- session_v %>%
    mutate(ID = paste0(LastName, " (", ParlGroupAbbreviation, "/", CantonAbbreviation, ")" )) %>% 
    select(ID, PersonNumber, ParlGroupAbbreviation, party, IdVote, Decision) %>% 
    mutate(Decision_new = case_when(
      Decision == 1 ~ 1,
      Decision == 2 ~ 6,
      !Decision %in% c(1, 2) ~ 9
      )
    ) %>%
    select(-Decision) %>% 
    pivot_wider(names_from = IdVote, values_from = Decision_new)

  # Generate rcObject
  l[[length(l) + 1]] <- rollcall(
    data = session_v_pivot %>% select(-(1:4)),
    yea = c(1),
    nay = c(6),
    missing = c(9),
    notInLegis = NA,
    legis.names = session_v_pivot$ID,
    vote.names = names(session_v_pivot %>% select(-(1:4))),
    legis.data = session_v_pivot %>% select(1:4),
  )
}

res <- dwnominate::dwnominate(l)
knutwannheden commented 3 years ago

I have attached my test data here: test.zip

To test:

  1. Unzip file containing test.rds.
  2. Start interactive R and run following commands:
    library(pscl)
    library(dplyr)
    library(tidyr)
    library(wnominate)
  3. Load test.rds into v: v <- readRDS('/path/to/test.rds')
  4. Run code from previous comment, which in my case provokes the error.
  5. Optionally restart R (saving workspace) and rerun last statement only.
wmay commented 3 years ago

I wasn't expecting people to put tibbles into the rollcall objects. That was the issue. Does the new version fix it for you?

knutwannheden commented 3 years ago

Unfortunately I still have the same problem with the latest HEAD. I will try to see if I can figure out a workaround on my end.

knutwannheden commented 3 years ago

What does the trick is to also convert the legis.data parameter to rollcall() using as.data.frame(). Possibly dwnominate could somehow do this or report a more comprehensible error message if it detects this issue.

wmay commented 3 years ago

Yup, that's what I did. 7ccb8b09c4d6a0097f3f694976d97af6295c22ad

(There's a separate issue if your list only has two rollcalls, but I assume your real data has more sessions.)

knutwannheden commented 3 years ago

Maybe I have to test it again, but I am quite certain that I still had the same problem with your fix in place and I had to add the as.data.frame() call on top of that in my code. So possibly there is another usage of the parameter which requires this.