R anesrake error: “Error in x + weights: non-numeric argument for binary operator” Ask Question

First-time poster. I am attempting to preform survey raking in R studio following this article from R-bloggers, using the anesrake package https://www.r-bloggers.com/survey-raking-an-illustration/.

First, I have created a list with my target variables (based on national averages of educational attainment and unemployment):

nivel_edu <- c("Sin Estudios", "Primaria",
        "Secundaria", "Superiores")

z1 <- c(3.9, 18.02, 49.54, 28.54)

nivel_edu <- as.factor(nivel_edu)

est_cis <- data.frame(nivel_edu,z1)


situ_laboral <- c("Ocupados", "Parados", "Inactivos")
z2 <- c(47.94, 6.6, 45.46)

situ_laboral  <-as.factor(situ_laboral)

lab_cis <- data.frame(situ_laboral, z2)

target1 <-with(est_cis, list(nivel_edu= wpct(nivel_edu,z1))) 

target2 <- with(lab_cis, list(situ_laboral= wpct(situ_laboral,z2)))

target.def <- c(target1, target2)

Then I have recoded the variables in the survey data so that they appear with the same labels Captura|390x109

However, when I try to use the aneraske function I get the following message: "Error in x + weights: non-numeric argument for binary operator". I do not understand why this is happening, as the only binary operator I am using is $caseID. My other variables, both in the target list and the survey dataframe, are factor. This is the code I am using for the anesrake function:

raking <- anesrake(target.def, data, data$caseID,
                   cap=5, choosemethod = "total",
                   type = "pctlim", pctlim=0.05)

Any help would be greatly appreciated!!

Hi, and welcome!

A reproducible example, called a reprex is a great way to attract more and better answers. Using the example in the documentation, here's what one looks like.

library(anesrake)
#> Loading required package: Hmisc
#> Loading required package: lattice
#> Loading required package: survival
#> Loading required package: Formula
#> Loading required package: ggplot2
#> 
#> Attaching package: 'Hmisc'
#> The following objects are masked from 'package:base':
#> 
#>     format.pval, units
#> Loading required package: weights
#> Loading required package: gdata
#> gdata: read.xls support for 'XLS' (Excel 97-2004) files ENABLED.
#> 
#> gdata: read.xls support for 'XLSX' (Excel 2007+) files ENABLED.
#> 
#> Attaching package: 'gdata'
#> The following object is masked from 'package:stats':
#> 
#>     nobs
#> The following object is masked from 'package:utils':
#> 
#>     object.size
#> The following object is masked from 'package:base':
#> 
#>     startsWith
#> Loading required package: mice
#> 
#> Attaching package: 'mice'
#> The following objects are masked from 'package:base':
#> 
#>     cbind, rbind
data("anes04")

anes04$caseid <- 1:length(anes04$age)

anes04$agecats <- cut(anes04$age, c(0, 25,35,45,55,65,99))
levels(anes04$agecats) <- c("age1824", "age2534", "age3544",
          "age4554", "age5564", "age6599")

marriedtarget <- c(.4, .6)

agetarg <- c(.10, .15, .17, .23, .22, .13)
names(agetarg) <- c("age1824", "age2534", "age3544",
          "age4554", "age5564", "age6599")

targets <- list(marriedtarget, agetarg)

names(targets) <- c("married", "agecats")

outsave <- anesrake(targets, anes04, caseid=anes04$caseid,
          verbose=TRUE)
#> [1] "Raking...Iteration 1"
#> [1] "Current iteration changed total weights by 303.931933308375"
#> [1] "Raking...Iteration 2"
#> [1] "Current iteration changed total weights by 50.8760710934304"
#> [1] "Raking...Iteration 3"
#> [1] "Current iteration changed total weights by 2.45181318049929"
#> [1] "Raking...Iteration 4"
#> [1] "Current iteration changed total weights by 0.115529921587497"
#> [1] "Raking...Iteration 5"
#> [1] "Current iteration changed total weights by 0.00543798477855262"
#> [1] "Raking...Iteration 6"
#> [1] "Current iteration changed total weights by 0.000255952672060356"
#> [1] "Raking...Iteration 7"
#> [1] "Current iteration changed total weights by 1.20470391882233e-05"
#> [1] "Raking...Iteration 8"
#> [1] "Current iteration changed total weights by 5.67023318742699e-07"
#> [1] "Raking...Iteration 9"
#> [1] "Current iteration changed total weights by 2.66883061206258e-08"
#> [1] "Raking...Iteration 10"
#> [1] "Current iteration changed total weights by 1.25607590995003e-09"
#> [1] "Raking...Iteration 11"
#> [1] "Current iteration changed total weights by 5.92315085867767e-11"
#> [1] "Raking...Iteration 12"
#> [1] "Current iteration changed total weights by 2.76700884427328e-12"
#> [1] "Raking...Iteration 13"
#> [1] "Current iteration changed total weights by 2.07389660999979e-13"
#> [1] "Raking...Iteration 14"
#> [1] "Current iteration changed total weights by 1.23678844943242e-13"
#> [1] "Raking...Iteration 15"
#> [1] "Current iteration changed total weights by 1.2356782264078e-13"
#> [1] "Raking converged in 15 iterations"

caseweights <- data.frame(cases=outsave$caseid, weights=outsave$weightvec)

summary(caseweights)
#>      cases           weights      
#>  Min.   :   1.0   Min.   :0.4665  
#>  1st Qu.: 303.8   1st Qu.:0.6956  
#>  Median : 606.5   Median :0.8864  
#>  Mean   : 606.5   Mean   :1.0000  
#>  3rd Qu.: 909.2   3rd Qu.:1.1874  
#>  Max.   :1212.0   Max.   :1.7870

summary(outsave)
#> $convergence
#> [1] "Complete convergence was achieved after 15 iterations"
#> 
#> $base.weights
#> [1] "No Base Weights Were Used"
#> 
#> $raking.variables
#> [1] "married" "agecats"
#> 
#> $weight.summary
#>    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
#>  0.4665  0.6956  0.8864  1.0000  1.1874  1.7870 
#> 
#> $selection.method
#> [1] "variable selection conducted using _pctlim_ - discrepancies selected using _total_."
#> 
#> $general.design.effect
#> [1] 1.128633
#> 
#> $married
#>       Target Unweighted N Unweighted %     Wtd N Wtd % Change in % Resid. Disc.
#> FALSE    0.6          563     0.464905  726.6693   0.6   0.1350950 0.000000e+00
#> TRUE     0.4          648     0.535095  484.4462   0.4  -0.1350950 5.551115e-17
#> Total    1.0         1211     1.000000 1211.1155   1.0   0.2701899 5.551115e-17
#>       Orig. Disc.
#> FALSE   0.1350950
#> TRUE   -0.1350950
#> Total   0.2701899
#> 
#> $agecats
#>         Target Unweighted N Unweighted %   Wtd N Wtd %  Change in %
#> age1824   0.10          150    0.1237624  121.20  0.10 -0.023762376
#> age2534   0.15          205    0.1691419  181.80  0.15 -0.019141914
#> age3544   0.17          217    0.1790429  206.04  0.17 -0.009042904
#> age4554   0.23          237    0.1955446  278.76  0.23  0.034455446
#> age5564   0.22          216    0.1782178  266.64  0.22  0.041782178
#> age6599   0.13          187    0.1542904  157.56  0.13 -0.024290429
#> Total     1.00         1212    1.0000000 1212.00  1.00  0.152475248
#>         Resid. Disc.  Orig. Disc.
#> age1824 0.000000e+00 -0.023762376
#> age2534 0.000000e+00 -0.019141914
#> age3544 0.000000e+00 -0.009042904
#> age4554 2.775558e-17  0.034455446
#> age5564 5.551115e-17  0.041782178
#> age6599 0.000000e+00 -0.024290429
#> Total   8.326673e-17  0.152475248

Created on 2020-01-17 by the reprex package (v0.3.0)

The difficulty in resolving the code you're having trouble with is that data is not specified. (It doesn't have to be all your data or even your data at all, just representative; often it's possible to convert a built-in data set to meet the need.) Another aside: data is also the name of a built-in function. It's good practice to use dat or some other non-reserved term.

According to the documentation the weightsvector argument is optional and

1 + NULL
numeric(0)

so that leaves x. Are you sure data$caseID is numeric?

Thank you very much for you answer and sorry for my late reply. I have created a reproducible example with the reprex function, hopefully this is more appropiate.

setwd("~/Datos")
library(anesrake)
library(tidyverse)
library(haven)

# Creation of targets

nivel_edu <- c("Sin Estudios", "Primaria",
               "Secundaria", "Superiores")
z1 <- c(3.9, 18.02, 49.54, 28.54)

nivel_edu <- as.factor(nivel_edu)

est_cis <- data.frame(nivel_edu,z1)


situ_laboral <- c("Ocupados", "Parados", "Inactivos")
z2 <- c(47.94, 6.6, 45.46)

situ_laboral  <-as.factor(situ_laboral)

lab_cis <- data.frame(situ_laboral, z2)

target1 <-with(est_cis, list(nivel_edu= wpct(nivel_edu,z1))) 

target2 <- with(lab_cis, list(situ_laboral= wpct(situ_laboral,z2)))

target.def <- c(target1, target2)


cyl <- read_sav("3245.sav")

df <- filter(cyl, CCAA==8)


# Recoding unemployment data

df$situ_laboral <- df$P33
df$situ_laboral[df$situ_laboral==7]<-1
df$situ_laboral[df$situ_laboral==2]<-10
df$situ_laboral[df$situ_laboral==6]<-10
df$situ_laboral[df$situ_laboral==10]<-3
df$situ_laboral[df$situ_laboral==4]<-2
df$situ_laboral[df$situ_laboral==5]<-2
df$situ_laboral[df$situ_laboral>7]<-NA
df$situ_laboral<-as.factor(df$situ_laboral)
df$situ_laboral <- factor(df$situ_laboral,
                          levels = c(1,2,3),
                          labels = c("Ocupados", "Parados", "Inactivos")) 
summary(df$situ_laboral)
#>  Ocupados   Parados Inactivos      NA's 
#>       832       205       550        10


# Recoding education data

df$nivel_edu <- df$P32A
df$nivel_edu[df$nivel_edu==3]<-10
df$nivel_edu[df$nivel_edu==5]<-10
df$nivel_edu[df$nivel_edu==7]<-10
df$nivel_edu[df$nivel_edu==4]<-3
df$nivel_edu[df$nivel_edu==6]<-4
df$nivel_edu[df$nivel_edu==10]<-5
df$nivel_edu[df$nivel_edu==8]<-6
df$nivel_edu[df$nivel_edu==9]<-6
df$nivel_edu<- ifelse(df$P32<=2,1, df$nivel_edu)
df$nivel_edu[df$nivel_edu==4]<-3
df$nivel_edu[df$nivel_edu==5]<-3
df$nivel_edu[df$nivel_edu==6]<-4
df$nivel_edu[df$nivel_edu==99]<-NA
df$nivel_edu<-as.factor(df$nivel_edu)
df$nivel_edu <- factor(df$nivel_edu,
                       levels = c(1,2,3,4),
                       labels = c("Sin Estudios", "Primaria", "Secundaria", "Superiores")) 
summary(df$nivel_edu)
#> Sin Estudios     Primaria   Secundaria   Superiores         NA's 
#>           54          308          861          369            5


# Raking 


df<- subset(df, select = c("nivel_edu", "situ_laboral", "VOTOSIMA"))
head(df)
#> # A tibble: 6 x 3
#>   nivel_edu  situ_laboral             VOTOSIMA
#>   <fct>      <fct>                   <dbl+lbl>
#> 1 Primaria   Ocupados     98 [No sabe todavía]
#> 2 Primaria   Inactivos     1 [PP]             
#> 3 Primaria   Inactivos    99 [N.C.]           
#> 4 Secundaria Ocupados     98 [No sabe todavía]
#> 5 Secundaria Ocupados     96 [En blanco]      
#> 6 Secundaria Ocupados      1 [PP]
df$caseID <- 1:nrow(df)
raking <- anesrake(target.def, df, df$caseID)
#> Error in x + weights: argumento no-numérico para operador binario

Hopefully this works better, again thanks a lot for your help (also sorry that the error appears in Spanish!!!).

I have also attempted to use a method similar to the one used in your example. In this case my target is only based on one variable (unemployment level), because I wanted to make the code as similar to yours as possible. The same error appears.

library(anesrake)
library(tidyverse)
library(haven)
cyl <- read_sav("3245.sav")

df <- filter(cyl, CCAA==8)

# Survey unemployment data

df$situ_laboral <- df$P33
df$situ_laboral[df$situ_laboral==7]<-1
df$situ_laboral[df$situ_laboral==2]<-10
df$situ_laboral[df$situ_laboral==6]<-10
df$situ_laboral[df$situ_laboral==10]<-3
df$situ_laboral[df$situ_laboral==4]<-2
df$situ_laboral[df$situ_laboral==5]<-2
df$situ_laboral[df$situ_laboral>7]<-NA
levels(df$situ_laboral) <- c("Ocupados", "Parados", "Inactivos") 

df$caseid <- 1:length(df$situ_laboral)

lab_targ <- c(47.94, 6.6,45.46)
names(lab_targ ) <- c("Ocupados", "Parados", "Inactivos")

targets <- list(lab_targ)

names(targets) <- c("situ_laboral")

df<- subset(df, select = c("situ_laboral", "VOTOSIMA"))
head(df)
#> # A tibble: 6 x 2
#>                                                  situ_laboral           VOTOSIMA
#>                                                     <dbl+lbl>          <dbl+lbl>
#> 1 1 [Trabaja]                                                 98 [No sabe todav…
#> 2 3 [Pensionista (anteriormente no ha trabajado, sus labores…  1 [PP]           
#> 3 3 [Pensionista (anteriormente no ha trabajado, sus labores… 99 [N.C.]         
#> 4 1 [Trabaja]                                                 98 [No sabe todav…
#> 5 1 [Trabaja]                                                 96 [En blanco]    
#> 6 1 [Trabaja]                                                  1 [PP]

outsave <- anesrake(targets, df, caseid=df$caseid,
                    verbose=TRUE)
#> Warning: Unknown or uninitialised column: 'caseid'.
#> Error in x + weights: argumento no-numérico para operador binario

¡No hay problema!

Two changes though.

df
#> function (x, df1, df2, ncp, log = FALSE) 
#> {
#>     if (missing(ncp)) 
#>         .Call(C_df, x, df1, df2, log)
#>     else .Call(C_dnf, x, df1, df2, ncp, log)
#> }
#> <bytecode: 0x7fdb2ab55158>
#> <environment: namespace:stats>

Created on 2020-01-19 by the reprex package (v0.3.0)

df() the function conflicts with df the data frame. mio_df or dat are preferable.

Second, I have nothing to substitute for 3245.sav because I don't know what form the data are in. It doesn't have to be the actual data or even as long as the actual data, just the same colnames and class of column.

The error translates to

One or the x or weights isn't numeric

I suspect its df

suppressPackageStartupMessages(library(anesrake))
suppressPackageStartupMessages(library(tidyverse)) 
suppressPackageStartupMessages(library(haven)) 

# Creation of targets
nivel_edu <- c("Sin Estudios", "Primaria",

               "Secundaria", "Superiores")

z1 <- c(3.9, 18.02, 49.54, 28.54)
nivel_edu <- as.factor(nivel_edu)
est_cis <- data.frame(nivel_edu,z1)
situ_laboral <- c("Ocupados", "Parados", "Inactivos")
z2 <- c(47.94, 6.6, 45.46)
situ_laboral  <-as.factor(situ_laboral)
lab_cis <- data.frame(situ_laboral, z2)
target1 <-with(est_cis, list(nivel_edu= wpct(nivel_edu,z1))) 
target2 <- with(lab_cis, list(situ_laboral= wpct(situ_laboral,z2)))
target.def <- c(target1, target2)
cyl <- read_sav("3245.sav")
#> Error: '3245.sav' does not exist in current working directory ('/private/var/folders/vw/p54wdfm95lq9wf8jkwxg_qpw0000gp/T/Rtmp52EHAr/reprex33e12040cb8a').

Created on 2020-01-19 by the reprex package (v0.3.0)

I have managed to detect the problem creating a similar dataset while doing the reproducible example. The problem was the class of the dataset of my survey, which was the following:

class(data)
#> "tbl_df"     "tbl"        "data.frame"

The solution was to do:

data <- as.data.frame(data)
class(data)
#>  "data.frame"

After doing this, the anesrake function worked.

Thank you so much for your advice, you have helped me solve a problem I was struggling with for days. Also, I believe learning how to do reproducible examples will help me solve future problems.

3 Likes

Great! Please mark *your answer (no false modesty!) the solution for the benefit of those to follow.

Again, it's best to avoid naming objects data because that is also the name of a built-in function. You can check with

data
#> function (..., list = character(), package = NULL, lib.loc = NULL, 
#>     verbose = getOption("verbose"), envir = .GlobalEnv, overwrite = TRUE) 
#> {
#>     fileExt <- function(x) {
#>         db <- grepl("\\.[^.]+\\.(gz|bz2|xz)$", x)
#>         ans <- sub(".*\\.", "", x)
#>         ans[db] <- sub(".*\\.([^.]+\\.)(gz|bz2|xz)$", "\\1\\2", 
#>             x[db])
#>         ans
#>     }
#>     names <- c(as.character(substitute(list(...))[-1L]), list)
#>     if (!is.null(package)) {
#>         if (!is.character(package)) 
#>             stop("'package' must be a character string or NULL")
#>         if (any(package %in% "base")) 
#>             warning("datasets have been moved from package 'base' to package 'datasets'")
#>         if (any(package %in% "stats")) 
#>             warning("datasets have been moved from package 'stats' to package 'datasets'")
#>         package[package %in% c("base", "stats")] <- "datasets"
#>     }
#>     paths <- find.package(package, lib.loc, verbose = verbose)
#>     if (is.null(lib.loc)) 
#>         paths <- c(path.package(package, TRUE), if (!length(package)) getwd(), 
#>             paths)
#>     paths <- unique(normalizePath(paths[file.exists(paths)]))
#>     paths <- paths[dir.exists(file.path(paths, "data"))]
#>     dataExts <- tools:::.make_file_exts("data")
#>     if (length(names) == 0L) {
#>         db <- matrix(character(), nrow = 0L, ncol = 4L)
#>         for (path in paths) {
#>             entries <- NULL
#>             packageName <- if (file_test("-f", file.path(path, 
#>                 "DESCRIPTION"))) 
#>                 basename(path)
#>             else "."
#>             if (file_test("-f", INDEX <- file.path(path, "Meta", 
#>                 "data.rds"))) {
#>                 entries <- readRDS(INDEX)
#>             }
#>             else {
#>                 dataDir <- file.path(path, "data")
#>                 entries <- tools::list_files_with_type(dataDir, 
#>                   "data")
#>                 if (length(entries)) {
#>                   entries <- unique(tools::file_path_sans_ext(basename(entries)))
#>                   entries <- cbind(entries, "")
#>                 }
#>             }
#>             if (NROW(entries)) {
#>                 if (is.matrix(entries) && ncol(entries) == 2L) 
#>                   db <- rbind(db, cbind(packageName, dirname(path), 
#>                     entries))
#>                 else warning(gettextf("data index for package %s is invalid and will be ignored", 
#>                   sQuote(packageName)), domain = NA, call. = FALSE)
#>             }
#>         }
#>         colnames(db) <- c("Package", "LibPath", "Item", "Title")
#>         footer <- if (missing(package)) 
#>             paste0("Use ", sQuote(paste("data(package =", ".packages(all.available = TRUE))")), 
#>                 "\n", "to list the data sets in all *available* packages.")
#>         else NULL
#>         y <- list(title = "Data sets", header = NULL, results = db, 
#>             footer = footer)
#>         class(y) <- "packageIQR"
#>         return(y)
#>     }
#>     paths <- file.path(paths, "data")
#>     for (name in names) {
#>         found <- FALSE
#>         for (p in paths) {
#>             tmp_env <- if (overwrite) 
#>                 envir
#>             else new.env()
#>             if (file_test("-f", file.path(p, "Rdata.rds"))) {
#>                 rds <- readRDS(file.path(p, "Rdata.rds"))
#>                 if (name %in% names(rds)) {
#>                   found <- TRUE
#>                   if (verbose) 
#>                     message(sprintf("name=%s:\t found in Rdata.rds", 
#>                       name), domain = NA)
#>                   thispkg <- sub(".*/([^/]*)/data$", "\\1", p)
#>                   thispkg <- sub("_.*$", "", thispkg)
#>                   thispkg <- paste0("package:", thispkg)
#>                   objs <- rds[[name]]
#>                   lazyLoad(file.path(p, "Rdata"), envir = tmp_env, 
#>                     filter = function(x) x %in% objs)
#>                   break
#>                 }
#>                 else if (verbose) 
#>                   message(sprintf("name=%s:\t NOT found in names() of Rdata.rds, i.e.,\n\t%s\n", 
#>                     name, paste(names(rds), collapse = ",")), 
#>                     domain = NA)
#>             }
#>             if (file_test("-f", file.path(p, "Rdata.zip"))) {
#>                 warning("zipped data found for package ", sQuote(basename(dirname(p))), 
#>                   ".\nThat is defunct, so please re-install the package.", 
#>                   domain = NA)
#>                 if (file_test("-f", fp <- file.path(p, "filelist"))) 
#>                   files <- file.path(p, scan(fp, what = "", quiet = TRUE))
#>                 else {
#>                   warning(gettextf("file 'filelist' is missing for directory %s", 
#>                     sQuote(p)), domain = NA)
#>                   next
#>                 }
#>             }
#>             else {
#>                 files <- list.files(p, full.names = TRUE)
#>             }
#>             files <- files[grep(name, files, fixed = TRUE)]
#>             if (length(files) > 1L) {
#>                 o <- match(fileExt(files), dataExts, nomatch = 100L)
#>                 paths0 <- dirname(files)
#>                 paths0 <- factor(paths0, levels = unique(paths0))
#>                 files <- files[order(paths0, o)]
#>             }
#>             if (length(files)) {
#>                 for (file in files) {
#>                   if (verbose) 
#>                     message("name=", name, ":\t file= ...", .Platform$file.sep, 
#>                       basename(file), "::\t", appendLF = FALSE, 
#>                       domain = NA)
#>                   ext <- fileExt(file)
#>                   if (basename(file) != paste0(name, ".", ext)) 
#>                     found <- FALSE
#>                   else {
#>                     found <- TRUE
#>                     zfile <- file
#>                     zipname <- file.path(dirname(file), "Rdata.zip")
#>                     if (file.exists(zipname)) {
#>                       Rdatadir <- tempfile("Rdata")
#>                       dir.create(Rdatadir, showWarnings = FALSE)
#>                       topic <- basename(file)
#>                       rc <- .External(C_unzip, zipname, topic, 
#>                         Rdatadir, FALSE, TRUE, FALSE, FALSE)
#>                       if (rc == 0L) 
#>                         zfile <- file.path(Rdatadir, topic)
#>                     }
#>                     if (zfile != file) 
#>                       on.exit(unlink(zfile))
#>                     switch(ext, R = , r = {
#>                       library("utils")
#>                       sys.source(zfile, chdir = TRUE, envir = tmp_env)
#>                     }, RData = , rdata = , rda = load(zfile, 
#>                       envir = tmp_env), TXT = , txt = , tab = , 
#>                       tab.gz = , tab.bz2 = , tab.xz = , txt.gz = , 
#>                       txt.bz2 = , txt.xz = assign(name, read.table(zfile, 
#>                         header = TRUE, as.is = FALSE), envir = tmp_env), 
#>                       CSV = , csv = , csv.gz = , csv.bz2 = , 
#>                       csv.xz = assign(name, read.table(zfile, 
#>                         header = TRUE, sep = ";", as.is = FALSE), 
#>                         envir = tmp_env), found <- FALSE)
#>                   }
#>                   if (found) 
#>                     break
#>                 }
#>                 if (verbose) 
#>                   message(if (!found) 
#>                     "*NOT* ", "found", domain = NA)
#>             }
#>             if (found) 
#>                 break
#>         }
#>         if (!found) {
#>             warning(gettextf("data set %s not found", sQuote(name)), 
#>                 domain = NA)
#>         }
#>         else if (!overwrite) {
#>             for (o in ls(envir = tmp_env, all.names = TRUE)) {
#>                 if (exists(o, envir = envir, inherits = FALSE)) 
#>                   warning(gettextf("an object named %s already exists and will not be overwritten", 
#>                     sQuote(o)))
#>                 else assign(o, get(o, envir = tmp_env, inherits = FALSE), 
#>                   envir = envir)
#>             }
#>             rm(tmp_env)
#>         }
#>     }
#>     invisible(names)
#> }
#> <bytecode: 0x7fd2814f07c8>
#> <environment: namespace:utils>

Created on 2020-01-19 by the reprex package (v0.3.0)

It's not clear to be why the function didn't like the tibble, which is just a data.frame in party attire, but that's a theoretical problem. Glad you found a practical solution!

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.