vctrs/ 0000755 0001762 0000144 00000000000 13623552332 011417 5 ustar ligges users vctrs/NAMESPACE 0000644 0001762 0000144 00000042547 13623211547 012652 0 ustar ligges users # Generated by roxygen2: do not edit by hand
S3method("!",vctrs_vctr)
S3method("!=",vctrs_vctr)
S3method("$",vctrs_list_of)
S3method("$",vctrs_rcrd)
S3method("$",vctrs_sclr)
S3method("$",vctrs_vctr)
S3method("$<-",vctrs_list_of)
S3method("$<-",vctrs_rcrd)
S3method("$<-",vctrs_sclr)
S3method("$<-",vctrs_vctr)
S3method("%%",vctrs_vctr)
S3method("%/%",vctrs_vctr)
S3method("&",vctrs_vctr)
S3method("*",vctrs_vctr)
S3method("+",vctrs_vctr)
S3method("-",vctrs_vctr)
S3method("/",vctrs_vctr)
S3method("<",vctrs_vctr)
S3method("<=",vctrs_vctr)
S3method("==",vctrs_vctr)
S3method(">",vctrs_vctr)
S3method(">=",vctrs_vctr)
S3method("[",vctrs_rcrd)
S3method("[",vctrs_sclr)
S3method("[",vctrs_unspecified)
S3method("[",vctrs_vctr)
S3method("[<-",vctrs_list_of)
S3method("[<-",vctrs_rcrd)
S3method("[<-",vctrs_sclr)
S3method("[<-",vctrs_vctr)
S3method("[[",vctrs_list_of)
S3method("[[",vctrs_rcrd)
S3method("[[",vctrs_sclr)
S3method("[[",vctrs_vctr)
S3method("[[<-",vctrs_list_of)
S3method("[[<-",vctrs_rcrd)
S3method("[[<-",vctrs_sclr)
S3method("[[<-",vctrs_vctr)
S3method("^",vctrs_vctr)
S3method("dim<-",vctrs_sclr)
S3method("dim<-",vctrs_vctr)
S3method("dimnames<-",vctrs_sclr)
S3method("dimnames<-",vctrs_vctr)
S3method("is.na<-",vctrs_sclr)
S3method("is.na<-",vctrs_vctr)
S3method("length<-",vctrs_rcrd)
S3method("length<-",vctrs_vctr)
S3method("levels<-",vctrs_sclr)
S3method("levels<-",vctrs_vctr)
S3method("names<-",vctrs_sclr)
S3method("names<-",vctrs_vctr)
S3method("|",vctrs_vctr)
S3method(Complex,vctrs_sclr)
S3method(Math,vctrs_sclr)
S3method(Math,vctrs_vctr)
S3method(Ops,vctrs_sclr)
S3method(Summary,vctrs_sclr)
S3method(Summary,vctrs_vctr)
S3method(anyDuplicated,vctrs_sclr)
S3method(anyDuplicated,vctrs_vctr)
S3method(anyNA,vctrs_vctr)
S3method(as.Date,vctrs_sclr)
S3method(as.Date,vctrs_vctr)
S3method(as.POSIXct,vctrs_sclr)
S3method(as.POSIXct,vctrs_vctr)
S3method(as.POSIXlt,vctrs_vctr)
S3method(as.character,vctrs_list_of)
S3method(as.character,vctrs_sclr)
S3method(as.character,vctrs_vctr)
S3method(as.data.frame,vctrs_sclr)
S3method(as.data.frame,vctrs_vctr)
S3method(as.double,vctrs_sclr)
S3method(as.double,vctrs_vctr)
S3method(as.integer,vctrs_sclr)
S3method(as.integer,vctrs_vctr)
S3method(as.list,vctrs_list_of)
S3method(as.list,vctrs_rcrd)
S3method(as.list,vctrs_sclr)
S3method(as.list,vctrs_vctr)
S3method(as.logical,vctrs_sclr)
S3method(as.logical,vctrs_vctr)
S3method(as_list_of,list)
S3method(as_list_of,vctrs_list_of)
S3method(c,vctrs_sclr)
S3method(c,vctrs_vctr)
S3method(cnd_body,vctrs_error_cast_lossy)
S3method(cnd_body,vctrs_error_recycle_incompatible_size)
S3method(cnd_body,vctrs_error_subscript_oob)
S3method(cnd_body,vctrs_error_subscript_type)
S3method(cnd_header,vctrs_error_cast_lossy)
S3method(cnd_header,vctrs_error_recycle_incompatible_size)
S3method(cnd_header,vctrs_error_subscript_oob)
S3method(cnd_header,vctrs_error_subscript_size)
S3method(cnd_header,vctrs_error_subscript_type)
S3method(conditionMessage,vctrs_error_cast_lossy)
S3method(diff,vctrs_vctr)
S3method(duplicated,vctrs_sclr)
S3method(duplicated,vctrs_vctr)
S3method(format,vctrs_group_rle)
S3method(format,vctrs_list_of)
S3method(format,vctrs_rcrd)
S3method(format,vctrs_vctr)
S3method(is.finite,vctrs_vctr)
S3method(is.infinite,vctrs_vctr)
S3method(is.na,vctrs_vctr)
S3method(is.nan,vctrs_vctr)
S3method(length,vctrs_rcrd)
S3method(levels,vctrs_sclr)
S3method(levels,vctrs_vctr)
S3method(max,vctrs_vctr)
S3method(mean,vctrs_vctr)
S3method(median,vctrs_vctr)
S3method(min,vctrs_vctr)
S3method(names,vctrs_rcrd)
S3method(obj_print_data,default)
S3method(obj_print_data,vctrs_list_of)
S3method(obj_print_data,vctrs_partial)
S3method(obj_print_footer,default)
S3method(obj_print_header,default)
S3method(obj_print_header,vctrs_group_rle)
S3method(obj_print_header,vctrs_partial)
S3method(obj_str_data,default)
S3method(obj_str_data,vctrs_rcrd)
S3method(obj_str_footer,default)
S3method(obj_str_header,default)
S3method(print,vctrs_sclr)
S3method(print,vctrs_unspecified)
S3method(print,vctrs_vctr)
S3method(quantile,vctrs_vctr)
S3method(range,vctrs_vctr)
S3method(rep,vctrs_rcrd)
S3method(rep,vctrs_vctr)
S3method(str,vctrs_vctr)
S3method(summary,vctrs_sclr)
S3method(summary,vctrs_vctr)
S3method(t,vctrs_sclr)
S3method(t,vctrs_vctr)
S3method(unique,vctrs_sclr)
S3method(unique,vctrs_vctr)
S3method(vec_arith,Date)
S3method(vec_arith,POSIXct)
S3method(vec_arith,default)
S3method(vec_arith,difftime)
S3method(vec_arith,factor)
S3method(vec_arith,logical)
S3method(vec_arith,numeric)
S3method(vec_arith.Date,Date)
S3method(vec_arith.Date,POSIXct)
S3method(vec_arith.Date,default)
S3method(vec_arith.Date,difftime)
S3method(vec_arith.Date,numeric)
S3method(vec_arith.POSIXct,Date)
S3method(vec_arith.POSIXct,POSIXct)
S3method(vec_arith.POSIXct,default)
S3method(vec_arith.POSIXct,difftime)
S3method(vec_arith.POSIXct,numeric)
S3method(vec_arith.difftime,Date)
S3method(vec_arith.difftime,MISSING)
S3method(vec_arith.difftime,POSIXct)
S3method(vec_arith.difftime,default)
S3method(vec_arith.difftime,difftime)
S3method(vec_arith.difftime,numeric)
S3method(vec_arith.logical,default)
S3method(vec_arith.logical,logical)
S3method(vec_arith.logical,numeric)
S3method(vec_arith.numeric,Date)
S3method(vec_arith.numeric,POSIXct)
S3method(vec_arith.numeric,default)
S3method(vec_arith.numeric,difftime)
S3method(vec_arith.numeric,logical)
S3method(vec_arith.numeric,numeric)
S3method(vec_cast,Date)
S3method(vec_cast,POSIXct)
S3method(vec_cast,POSIXlt)
S3method(vec_cast,character)
S3method(vec_cast,complex)
S3method(vec_cast,data.frame)
S3method(vec_cast,default)
S3method(vec_cast,difftime)
S3method(vec_cast,double)
S3method(vec_cast,factor)
S3method(vec_cast,integer)
S3method(vec_cast,integer64)
S3method(vec_cast,list)
S3method(vec_cast,logical)
S3method(vec_cast,raw)
S3method(vec_cast,vctrs_list_of)
S3method(vec_cast,vctrs_rcrd)
S3method(vec_cast,vctrs_vctr)
S3method(vec_cast.Date,Date)
S3method(vec_cast.Date,POSIXt)
S3method(vec_cast.Date,character)
S3method(vec_cast.Date,default)
S3method(vec_cast.Date,double)
S3method(vec_cast.Date,list)
S3method(vec_cast.POSIXct,Date)
S3method(vec_cast.POSIXct,POSIXct)
S3method(vec_cast.POSIXct,POSIXlt)
S3method(vec_cast.POSIXct,character)
S3method(vec_cast.POSIXct,default)
S3method(vec_cast.POSIXct,double)
S3method(vec_cast.POSIXct,list)
S3method(vec_cast.POSIXlt,Date)
S3method(vec_cast.POSIXlt,POSIXct)
S3method(vec_cast.POSIXlt,POSIXlt)
S3method(vec_cast.POSIXlt,character)
S3method(vec_cast.POSIXlt,default)
S3method(vec_cast.POSIXlt,double)
S3method(vec_cast.POSIXlt,list)
S3method(vec_cast.character,character)
S3method(vec_cast.character,default)
S3method(vec_cast.character,difftime)
S3method(vec_cast.character,double)
S3method(vec_cast.character,factor)
S3method(vec_cast.character,integer)
S3method(vec_cast.character,integer64)
S3method(vec_cast.character,list)
S3method(vec_cast.character,logical)
S3method(vec_cast.complex,complex)
S3method(vec_cast.complex,default)
S3method(vec_cast.complex,double)
S3method(vec_cast.complex,integer)
S3method(vec_cast.complex,list)
S3method(vec_cast.complex,logical)
S3method(vec_cast.data.frame,data.frame)
S3method(vec_cast.data.frame,default)
S3method(vec_cast.data.frame,list)
S3method(vec_cast.difftime,default)
S3method(vec_cast.difftime,difftime)
S3method(vec_cast.difftime,double)
S3method(vec_cast.difftime,list)
S3method(vec_cast.double,character)
S3method(vec_cast.double,default)
S3method(vec_cast.double,double)
S3method(vec_cast.double,integer)
S3method(vec_cast.double,integer64)
S3method(vec_cast.double,list)
S3method(vec_cast.double,logical)
S3method(vec_cast.factor,character)
S3method(vec_cast.factor,default)
S3method(vec_cast.factor,factor)
S3method(vec_cast.factor,list)
S3method(vec_cast.integer,character)
S3method(vec_cast.integer,default)
S3method(vec_cast.integer,double)
S3method(vec_cast.integer,integer)
S3method(vec_cast.integer,integer64)
S3method(vec_cast.integer,list)
S3method(vec_cast.integer,logical)
S3method(vec_cast.integer64,character)
S3method(vec_cast.integer64,default)
S3method(vec_cast.integer64,double)
S3method(vec_cast.integer64,integer)
S3method(vec_cast.integer64,integer64)
S3method(vec_cast.integer64,logical)
S3method(vec_cast.list,data.frame)
S3method(vec_cast.list,default)
S3method(vec_cast.list,list)
S3method(vec_cast.list,vctrs_list_of)
S3method(vec_cast.list,vctrs_rcrd)
S3method(vec_cast.list,vctrs_vctr)
S3method(vec_cast.logical,character)
S3method(vec_cast.logical,default)
S3method(vec_cast.logical,double)
S3method(vec_cast.logical,integer)
S3method(vec_cast.logical,integer64)
S3method(vec_cast.logical,list)
S3method(vec_cast.logical,logical)
S3method(vec_cast.raw,default)
S3method(vec_cast.raw,list)
S3method(vec_cast.raw,raw)
S3method(vec_cast.vctrs_list_of,default)
S3method(vec_cast.vctrs_list_of,list)
S3method(vec_cast.vctrs_list_of,vctrs_list_of)
S3method(vec_cast.vctrs_rcrd,default)
S3method(vec_cast.vctrs_rcrd,vctrs_rcrd)
S3method(vec_cast.vctrs_vctr,default)
S3method(vec_math,Date)
S3method(vec_math,POSIXct)
S3method(vec_math,default)
S3method(vec_math,factor)
S3method(vec_math,vctrs_rcrd)
S3method(vec_proxy,AsIs)
S3method(vec_proxy,Date)
S3method(vec_proxy,POSIXct)
S3method(vec_proxy,POSIXlt)
S3method(vec_proxy,default)
S3method(vec_proxy,vctrs_list_of)
S3method(vec_proxy,vctrs_rcrd)
S3method(vec_proxy,vctrs_vctr)
S3method(vec_proxy_compare,POSIXlt)
S3method(vec_proxy_compare,data.frame)
S3method(vec_proxy_compare,default)
S3method(vec_proxy_compare,integer64)
S3method(vec_proxy_compare,raw)
S3method(vec_proxy_compare,vctrs_rcrd)
S3method(vec_proxy_equal,default)
S3method(vec_ptype2,Date)
S3method(vec_ptype2,POSIXt)
S3method(vec_ptype2,character)
S3method(vec_ptype2,complex)
S3method(vec_ptype2,data.frame)
S3method(vec_ptype2,default)
S3method(vec_ptype2,difftime)
S3method(vec_ptype2,double)
S3method(vec_ptype2,factor)
S3method(vec_ptype2,integer)
S3method(vec_ptype2,integer64)
S3method(vec_ptype2,list)
S3method(vec_ptype2,logical)
S3method(vec_ptype2,ordered)
S3method(vec_ptype2,raw)
S3method(vec_ptype2,vctrs_list_of)
S3method(vec_ptype2,vctrs_partial_factor)
S3method(vec_ptype2,vctrs_partial_frame)
S3method(vec_ptype2,vctrs_unspecified)
S3method(vec_ptype2,vctrs_vctr)
S3method(vec_ptype2.Date,Date)
S3method(vec_ptype2.Date,POSIXt)
S3method(vec_ptype2.Date,default)
S3method(vec_ptype2.Date,vctrs_unspecified)
S3method(vec_ptype2.POSIXt,Date)
S3method(vec_ptype2.POSIXt,POSIXt)
S3method(vec_ptype2.POSIXt,default)
S3method(vec_ptype2.POSIXt,vctrs_unspecified)
S3method(vec_ptype2.character,character)
S3method(vec_ptype2.character,default)
S3method(vec_ptype2.character,factor)
S3method(vec_ptype2.character,ordered)
S3method(vec_ptype2.character,vctrs_unspecified)
S3method(vec_ptype2.complex,complex)
S3method(vec_ptype2.complex,default)
S3method(vec_ptype2.complex,double)
S3method(vec_ptype2.complex,integer)
S3method(vec_ptype2.data.frame,data.frame)
S3method(vec_ptype2.data.frame,default)
S3method(vec_ptype2.data.frame,vctrs_partial_frame)
S3method(vec_ptype2.difftime,default)
S3method(vec_ptype2.difftime,difftime)
S3method(vec_ptype2.difftime,vctrs_unspecified)
S3method(vec_ptype2.double,complex)
S3method(vec_ptype2.double,default)
S3method(vec_ptype2.double,double)
S3method(vec_ptype2.double,integer)
S3method(vec_ptype2.double,logical)
S3method(vec_ptype2.double,vctrs_unspecified)
S3method(vec_ptype2.factor,character)
S3method(vec_ptype2.factor,default)
S3method(vec_ptype2.factor,factor)
S3method(vec_ptype2.factor,ordered)
S3method(vec_ptype2.factor,vctrs_partial_factor)
S3method(vec_ptype2.factor,vctrs_unspecified)
S3method(vec_ptype2.integer,complex)
S3method(vec_ptype2.integer,default)
S3method(vec_ptype2.integer,double)
S3method(vec_ptype2.integer,integer)
S3method(vec_ptype2.integer,integer64)
S3method(vec_ptype2.integer,logical)
S3method(vec_ptype2.integer,vctrs_unspecified)
S3method(vec_ptype2.integer64,default)
S3method(vec_ptype2.integer64,integer)
S3method(vec_ptype2.integer64,integer64)
S3method(vec_ptype2.integer64,logical)
S3method(vec_ptype2.integer64,vctrs_unspecified)
S3method(vec_ptype2.list,default)
S3method(vec_ptype2.list,list)
S3method(vec_ptype2.list,vctrs_list_of)
S3method(vec_ptype2.list,vctrs_unspecified)
S3method(vec_ptype2.logical,default)
S3method(vec_ptype2.logical,double)
S3method(vec_ptype2.logical,integer)
S3method(vec_ptype2.logical,integer64)
S3method(vec_ptype2.logical,logical)
S3method(vec_ptype2.logical,vctrs_unspecified)
S3method(vec_ptype2.ordered,character)
S3method(vec_ptype2.ordered,default)
S3method(vec_ptype2.ordered,factor)
S3method(vec_ptype2.ordered,ordered)
S3method(vec_ptype2.ordered,vctrs_unspecified)
S3method(vec_ptype2.raw,default)
S3method(vec_ptype2.raw,raw)
S3method(vec_ptype2.vctrs_list_of,default)
S3method(vec_ptype2.vctrs_list_of,list)
S3method(vec_ptype2.vctrs_list_of,vctrs_list_of)
S3method(vec_ptype2.vctrs_list_of,vctrs_unspecified)
S3method(vec_ptype2.vctrs_partial_factor,factor)
S3method(vec_ptype2.vctrs_partial_factor,vctrs_partial_factor)
S3method(vec_ptype2.vctrs_partial_frame,data.frame)
S3method(vec_ptype2.vctrs_partial_frame,vctrs_partial_frame)
S3method(vec_ptype_abbr,AsIs)
S3method(vec_ptype_abbr,Date)
S3method(vec_ptype_abbr,POSIXt)
S3method(vec_ptype_abbr,data.frame)
S3method(vec_ptype_abbr,default)
S3method(vec_ptype_abbr,difftime)
S3method(vec_ptype_abbr,factor)
S3method(vec_ptype_abbr,integer64)
S3method(vec_ptype_abbr,ordered)
S3method(vec_ptype_abbr,vctrs_list_of)
S3method(vec_ptype_abbr,vctrs_partial_factor)
S3method(vec_ptype_abbr,vctrs_partial_frame)
S3method(vec_ptype_abbr,vctrs_unspecified)
S3method(vec_ptype_finalise,default)
S3method(vec_ptype_finalise,vctrs_partial)
S3method(vec_ptype_finalise,vctrs_partial_factor)
S3method(vec_ptype_finalise,vctrs_partial_frame)
S3method(vec_ptype_full,AsIs)
S3method(vec_ptype_full,Date)
S3method(vec_ptype_full,POSIXct)
S3method(vec_ptype_full,POSIXlt)
S3method(vec_ptype_full,data.frame)
S3method(vec_ptype_full,default)
S3method(vec_ptype_full,difftime)
S3method(vec_ptype_full,factor)
S3method(vec_ptype_full,integer64)
S3method(vec_ptype_full,ordered)
S3method(vec_ptype_full,vctrs_list_of)
S3method(vec_ptype_full,vctrs_partial_factor)
S3method(vec_ptype_full,vctrs_partial_frame)
S3method(vec_restore,AsIs)
S3method(vec_restore,data.frame)
S3method(vec_restore,default)
S3method(vec_restore,vctrs_rcrd)
S3method(vec_restore,vctrs_vctr)
S3method(xtfrm,vctrs_sclr)
S3method(xtfrm,vctrs_vctr)
export("%0%")
export("field<-")
export("vec_slice<-")
export(MISSING)
export(allow_lossy_cast)
export(as_list_of)
export(field)
export(fields)
export(is_list_of)
export(is_partial)
export(list_of)
export(maybe_lossy_cast)
export(n_fields)
export(new_data_frame)
export(new_date)
export(new_datetime)
export(new_duration)
export(new_factor)
export(new_list_of)
export(new_ordered)
export(new_partial)
export(new_rcrd)
export(new_vctr)
export(num_as_location)
export(num_as_location2)
export(obj_print)
export(obj_print_data)
export(obj_print_footer)
export(obj_print_header)
export(obj_str)
export(obj_str_data)
export(obj_str_footer)
export(obj_str_header)
export(partial_factor)
export(partial_frame)
export(s3_register)
export(stop_incompatible_cast)
export(stop_incompatible_op)
export(stop_incompatible_size)
export(stop_incompatible_type)
export(unspecified)
export(validate_list_of)
export(vec_arith)
export(vec_arith.Date)
export(vec_arith.POSIXct)
export(vec_arith.difftime)
export(vec_arith.logical)
export(vec_arith.numeric)
export(vec_arith_base)
export(vec_as_index)
export(vec_as_location)
export(vec_as_location2)
export(vec_as_names)
export(vec_as_names_legacy)
export(vec_as_subscript)
export(vec_as_subscript2)
export(vec_assert)
export(vec_assign)
export(vec_c)
export(vec_cast)
export(vec_cast.Date)
export(vec_cast.POSIXct)
export(vec_cast.POSIXlt)
export(vec_cast.character)
export(vec_cast.complex)
export(vec_cast.data.frame)
export(vec_cast.difftime)
export(vec_cast.double)
export(vec_cast.factor)
export(vec_cast.integer)
export(vec_cast.integer64)
export(vec_cast.list)
export(vec_cast.logical)
export(vec_cast.raw)
export(vec_cast.vctrs_list_of)
export(vec_cast_common)
export(vec_cbind)
export(vec_chop)
export(vec_compare)
export(vec_count)
export(vec_data)
export(vec_default_cast)
export(vec_default_ptype2)
export(vec_duplicate_any)
export(vec_duplicate_detect)
export(vec_duplicate_id)
export(vec_empty)
export(vec_equal)
export(vec_equal_na)
export(vec_group_id)
export(vec_group_loc)
export(vec_group_rle)
export(vec_in)
export(vec_init)
export(vec_init_along)
export(vec_is)
export(vec_is_empty)
export(vec_is_list)
export(vec_list_cast)
export(vec_match)
export(vec_math)
export(vec_math_base)
export(vec_order)
export(vec_proxy)
export(vec_proxy_compare)
export(vec_proxy_equal)
export(vec_ptype)
export(vec_ptype2)
export(vec_ptype2.Date)
export(vec_ptype2.POSIXt)
export(vec_ptype2.character)
export(vec_ptype2.complex)
export(vec_ptype2.data.frame)
export(vec_ptype2.difftime)
export(vec_ptype2.double)
export(vec_ptype2.factor)
export(vec_ptype2.integer)
export(vec_ptype2.integer64)
export(vec_ptype2.list)
export(vec_ptype2.logical)
export(vec_ptype2.ordered)
export(vec_ptype2.raw)
export(vec_ptype2.vctrs_list_of)
export(vec_ptype2.vctrs_unspecified)
export(vec_ptype_abbr)
export(vec_ptype_common)
export(vec_ptype_finalise)
export(vec_ptype_full)
export(vec_ptype_show)
export(vec_rbind)
export(vec_recycle)
export(vec_recycle_common)
export(vec_repeat)
export(vec_restore)
export(vec_seq_along)
export(vec_size)
export(vec_size_common)
export(vec_slice)
export(vec_sort)
export(vec_split)
export(vec_type)
export(vec_type2)
export(vec_type_common)
export(vec_unique)
export(vec_unique_count)
export(vec_unique_loc)
import(rlang)
importFrom(stats,median)
importFrom(stats,quantile)
useDynLib(vctrs, .registration = TRUE)
vctrs/README.md 0000644 0001762 0000144 00000007377 13622451540 012712 0 ustar ligges users
# vctrs
[](https://codecov.io/github/r-lib/vctrs?branch=master)
[](https://www.tidyverse.org/lifecycle/#maturing)

There are three main goals to the vctrs package, each described in a
vignette:
- To propose `vec_size()` and `vec_ptype()` as alternatives to
`length()` and `class()`; `vignette("type-size")`. These definitions
are paired with a framework for size-recycling and type-coercion.
`ptype` should evoke the notion of a prototype, i.e. the original or
typical form of something.
- To define size- and type-stability as desirable function properties,
use them to analyse existing base functions, and to propose better
alternatives; `vignette("stability")`. This work has been
particularly motivated by thinking about the ideal properties of
`c()`, `ifelse()`, and `rbind()`.
- To provide a new `vctr` base class that makes it easy to create new
S3 vectors; `vignette("s3-vector")`. vctrs provides methods for many
base generics in terms of a few new vctrs generics, making
implementation considerably simpler and more robust.
vctrs is a developer-focussed package. Understanding and extending vctrs
requires some effort from developers, but should be invisible to most
users. It’s our hope that having an underlying theory will mean that
users can build up an accurate mental model without explicitly learning
the theory. vctrs will typically be used by other packages, making it
easy for them to provide new classes of S3 vectors that are supported
throughout the tidyverse (and beyond). For that reason, vctrs has few
dependencies.
## Installation
Install vctrs from CRAN with:
``` r
install.packages("vctrs")
```
Alternatively, if you need the development version, install it with:
``` r
# install.packages("devtools")
devtools::install_github("r-lib/vctrs")
```
## Usage
``` r
library(vctrs)
# Sizes
str(vec_size_common(1, 1:10))
#> int 10
str(vec_recycle_common(1, 1:10))
#> List of 2
#> $ : num [1:10] 1 1 1 1 1 1 1 1 1 1
#> $ : int [1:10] 1 2 3 4 5 6 7 8 9 10
# Prototypes
str(vec_ptype_common(FALSE, 1L, 2.5))
#> num(0)
str(vec_cast_common(FALSE, 1L, 2.5))
#> List of 3
#> $ : num 0
#> $ : num 1
#> $ : num 2.5
```
## Motivation
The original motivation for vctrs comes from two separate but related
problems. The first problem is that `base::c()` has rather undesirable
behaviour when you mix different S3 vectors:
``` r
# combining factors makes integers
c(factor("a"), factor("b"))
#> [1] 1 1
# combining dates and date-times gives incorrect values; also, order matters
dt <- as.Date("2020-01-01")
dttm <- as.POSIXct(dt)
c(dt, dttm)
#> [1] "2020-01-01" "4321940-06-07"
c(dttm, dt)
#> [1] "2019-12-31 16:00:00 PST" "1969-12-31 21:04:22 PST"
```
This behaviour arises because `c()` has dual purposes: as well as its
primary duty of combining vectors, it has a secondary duty of stripping
attributes. For example, `?POSIXct` suggests that you should use `c()`
if you want to reset the timezone.
The second problem is that `dplyr::bind_rows()` is not extensible by
others. Currently, it handles arbitrary S3 classes using heuristics, but
these often fail, and it feels like we really need to think through the
problem in order to build a principled solution. This intersects with
the need to cleanly support more types of data frame columns, including
lists of data frames, data frames, and matrices.
vctrs/man/ 0000755 0001762 0000144 00000000000 13623045240 012165 5 ustar ligges users vctrs/man/vec_duplicate.Rd 0000644 0001762 0000144 00000003771 13622451540 015276 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/dictionary.R
\name{vec_duplicate}
\alias{vec_duplicate}
\alias{vec_duplicate_any}
\alias{vec_duplicate_detect}
\alias{vec_duplicate_id}
\title{Find duplicated values}
\usage{
vec_duplicate_any(x)
vec_duplicate_detect(x)
vec_duplicate_id(x)
}
\arguments{
\item{x}{A vector (including a data frame).}
}
\value{
\itemize{
\item \code{vec_duplicate_any()}: a logical vector of length 1.
\item \code{vec_duplicate_detect()}: a logical vector the same length as \code{x}.
\item \code{vec_duplicate_id()}: an integer vector the same length as \code{x}.
}
}
\description{
\itemize{
\item \code{vec_duplicate_any()}: detects the presence of duplicated values,
similar to \code{\link[=anyDuplicated]{anyDuplicated()}}.
\item \code{vec_duplicate_detect()}: returns a logical vector describing if each
element of the vector is duplicated elsewhere. Unlike \code{\link[=duplicated]{duplicated()}}, it
reports all duplicated values, not just the second and subsequent
repetitions.
\item \code{vec_duplicate_id()}: returns an integer vector giving the location of
the first occurrence of the value.
}
}
\section{Missing values}{
In most cases, missing values are not considered to be equal, i.e.
\code{NA == NA} is not \code{TRUE}. This behaviour would be unappealing here,
so these functions consider all \code{NAs} to be equal. (Similarly,
all \code{NaN} are also considered to be equal.)
}
\examples{
vec_duplicate_any(1:10)
vec_duplicate_any(c(1, 1:10))
x <- c(10, 10, 20, 30, 30, 40)
vec_duplicate_detect(x)
# Note that `duplicated()` doesn't consider the first instance to
# be a duplicate
duplicated(x)
# Identify elements of a vector by the location of the first element that
# they're equal to:
vec_duplicate_id(x)
# Location of the unique values:
vec_unique_loc(x)
# Equivalent to `duplicated()`:
vec_duplicate_id(x) == seq_along(x)
}
\seealso{
\code{\link[=vec_unique]{vec_unique()}} for functions that work with the dual of duplicated
values: unique values.
}
vctrs/man/vec_seq_along.Rd 0000644 0001762 0000144 00000001355 13622451540 015270 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/size.R
\name{vec_seq_along}
\alias{vec_seq_along}
\alias{vec_init_along}
\title{Useful sequences}
\usage{
vec_seq_along(x)
vec_init_along(x, y = x)
}
\arguments{
\item{x, y}{Vectors}
}
\value{
\itemize{
\item \code{vec_seq_along()} an integer vector with the same size as \code{x}.
\item \code{vec_init_along()} a vector with the same type as \code{x} and the same size
as \code{y}.
}
}
\description{
\code{vec_seq_along()} is equivalent to \code{\link[=seq_along]{seq_along()}} but uses size, not length.
\code{vec_init_along()} creates a vector of missing values with size matching
an existing object.
}
\examples{
vec_seq_along(mtcars)
vec_init_along(head(mtcars))
}
vctrs/man/vec_list_cast.Rd 0000644 0001762 0000144 00000001421 13622451540 015277 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/cast-list.R
\name{vec_list_cast}
\alias{vec_list_cast}
\title{Cast a list to vector of specific type}
\usage{
vec_list_cast(x, to, ..., x_arg = "", to_arg = "")
}
\arguments{
\item{x}{A list}
\item{to}{Type to coerce to}
\item{...}{These dots are for future extensions and must be empty.}
}
\description{
This is a function for developers to use when extending vctrs. It casts
a list to a more specific vectoring type, keeping the length constant.
It does this by discarding (with a warning), any elements after the 1.
It is called from \code{vec_cast.XYZ.list()} methods to preserve symmetry with
\code{vec_cast.list.XYZ()}.
}
\details{
See \code{vignette("s3-vector")} for details.
}
\keyword{internal}
vctrs/man/vec_ptype2.Rd 0000644 0001762 0000144 00000005320 13622451540 014537 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/type-bare.R, R/type2.R
\name{vec_ptype2.logical}
\alias{vec_ptype2.logical}
\alias{vec_ptype2.integer}
\alias{vec_ptype2.double}
\alias{vec_ptype2.complex}
\alias{vec_ptype2.character}
\alias{vec_ptype2.raw}
\alias{vec_ptype2.list}
\alias{vec_ptype2}
\alias{vec_default_ptype2}
\title{Find the common type for a pair of vector types}
\usage{
\method{vec_ptype2}{logical}(x, y, ..., x_arg = "x", y_arg = "y")
\method{vec_ptype2}{integer}(x, y, ..., x_arg = "x", y_arg = "y")
\method{vec_ptype2}{double}(x, y, ..., x_arg = "x", y_arg = "y")
\method{vec_ptype2}{complex}(x, y, ..., x_arg = "x", y_arg = "y")
\method{vec_ptype2}{character}(x, y, ..., x_arg = "x", y_arg = "y")
\method{vec_ptype2}{raw}(x, y, ..., x_arg = "x", y_arg = "y")
\method{vec_ptype2}{list}(x, y, ..., x_arg = "x", y_arg = "y")
vec_ptype2(x, y, ..., x_arg = "x", y_arg = "y")
vec_default_ptype2(x, y, ..., x_arg = "x", y_arg = "y")
}
\arguments{
\item{x, y}{Vector types.}
\item{...}{These dots are for future extensions and must be empty.}
\item{x_arg, y_arg}{Argument names for \code{x} and \code{y}. These are used
in error messages to inform the user about the locations of
incompatible types (see \code{\link[=stop_incompatible_type]{stop_incompatible_type()}}).}
}
\description{
\code{vec_ptype2()} finds the common type for a pair of vectors, or dies trying.
It forms the foundation of the vctrs type system, along with \code{\link[=vec_cast]{vec_cast()}}.
This powers type coercion but should not usually be called directly;
instead call \code{\link[=vec_ptype_common]{vec_ptype_common()}}.
}
\section{Coercion rules}{
vctrs thinks of the vector types as forming a partially ordered set, or
poset. Then finding the common type from a set of types is a matter of
finding the least-upper-bound; if the least-upper-bound does not exist,
there is no common type. This is the case for many pairs of 1d vectors.
The poset of the most important base vectors is shown below:
(where datetime stands for \code{POSIXt}, and date for \code{Date})
\figure{coerce.png}
}
\section{S3 dispatch}{
\code{vec_ptype2()} dispatches on both arguments. This is implemented by having
methods of \code{vec_ptype2()}, e.g. \code{vec_ptype2.integer()} also be S3 generics,
which call e.g. \code{vec_ptype2.integer.double()}. \code{vec_ptype2.x.y()} must
return the same value as \code{vec_ptype2.y.x()}; this is currently not enforced,
but should be tested.
Whenever you implement a \code{vec_ptype2.new_class()} generic/method,
make sure to always provide \code{vec_ptype2.new_class.default()}. It
should normally call \code{vec_default_ptype2()}.
See \code{vignette("s3-vector")} for full details.
}
\keyword{internal}
vctrs/man/new_rcrd.Rd 0000644 0001762 0000144 00000001674 13622451540 014272 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/type-rcrd.R
\name{new_rcrd}
\alias{new_rcrd}
\alias{ses}
\alias{rcrd}
\title{rcrd (record) S3 class}
\usage{
new_rcrd(fields, ..., class = character())
}
\arguments{
\item{fields}{A list. It must possess the following properties:
\itemize{
\item no attributes (apart from names)
\item syntactic names
\item length 1 or greater
\item elements are vectors
\item elements have equal length
}}
\item{...}{Additional attributes}
\item{class}{Name of subclass.}
}
\description{
The rcrd class extends \link{vctr}. A rcrd is composed of 1 or more \link{field}s,
which must be vectors of the same length. Is designed specifically for
classes that can naturally be decomposed into multiple vectors of the same
length, like \link{POSIXlt}, but where the organisation should be considered
an implementation detail invisible to the user (unlike a \link{data.frame}).
}
\keyword{internal}
vctrs/man/new_partial.Rd 0000644 0001762 0000144 00000001723 13622451540 014767 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/partial.R
\name{new_partial}
\alias{new_partial}
\alias{is_partial}
\alias{vec_ptype_finalise}
\title{Partial type}
\usage{
new_partial(..., class = character())
is_partial(x)
vec_ptype_finalise(x, ...)
}
\arguments{
\item{...}{Attributes of the partial type}
\item{class}{Name of subclass.}
}
\description{
Use \code{new_partial()} when constructing a new partial type subclass;
and use \code{is_partial()} to test if an type is partial. All subclasses
need to provide a \code{vec_ptype_finalise()} method.
}
\details{
As the name suggests, a partial type \emph{partially} specifies a type, and
it must be combined with data to yield a full type. A useful example
of a partial type is \code{\link[=partial_frame]{partial_frame()}}, which makes it possible to
specify the type of just a few columns in a data frame. Use this constructor
if you're making your own partial type.
}
\keyword{internal}
vctrs/man/faq/ 0000755 0001762 0000144 00000000000 13622451540 012737 5 ustar ligges users vctrs/man/faq/internal/ 0000755 0001762 0000144 00000000000 13622451540 014553 5 ustar ligges users vctrs/man/faq/internal/ptype2-identity.Rmd 0000644 0001762 0000144 00000006120 13622451540 020270 0 ustar ligges users
```{r, child = "setup.Rmd", include = FALSE}
```
## Promotion monoid
Promotions (i.e. automatic coercions) should always transform inputs to their richer type to avoid losing values of precision. `vec_ptype2()` returns the _richer_ type of two vectors, or throws an incompatible type error if none of the two vector types include the other. For example, the richer type of integer and double is the latter because double covers a larger range of values than integer.
`vec_ptype2()` is a [monoid](https://en.wikipedia.org/wiki/Monoid) over vectors, which in practical terms means that it is a well behaved operation for [reduction](https://purrr.tidyverse.org/reference/reduce.html). Reduction is an important operation for promotions because that is how the richer type of multiple elements is computed. As a monoid, `vec_ptype2()` needs an identity element, i.e. a value that doesn't change the result of the reduction. vctrs has two identity values, `NULL` and __unspecified__ vectors.
## The `NULL` identity
As an identity element that shouldn't influence the determination of the common type of a set of vectors, `NULL` is promoted to any type:
```{r}
vec_ptype2(NULL, "")
vec_ptype2(1L, NULL)
```
The common type of `NULL` and `NULL` is the identity `NULL`:
```{r}
vec_ptype2(NULL, NULL)
```
This way the result of `vec_ptype2(NULL, NULL)` does not influence subsequent promotions:
```{r}
vec_ptype2(
vec_ptype2(NULL, NULL),
""
)
```
## Unspecified vectors
In the vctrs coercion system, logical vectors of missing values are also automatically promoted to the type of any other vector, just like `NULL`. We call these vectors unspecified. The special coercion semantics of unspecified vectors serve two purposes:
1. It makes it possible to assign vectors of `NA` inside any type of vectors, even when they are not coercible with logical:
```{r}
x <- letters[1:5]
vec_assign(x, 1:2, c(NA, NA))
```
2. We can't put `NULL` in a data frame, so we need an identity element that behaves more like a vector. Logical vectors of `NA` seem a natural fit for this.
Unspecified vectors are thus promoted to any other type, just like `NULL`:
```{r}
vec_ptype2(NA, "")
vec_ptype2(1L, c(NA, NA))
```
## Finalising common types
vctrs has an internal vector type of class `vctrs_unspecified`. Users normally don't see such vectors in the wild, but they do come up when taking the common type of an unspecified vector with another identity value:
```{r}
vec_ptype2(NA, NA)
vec_ptype2(NA, NULL)
vec_ptype2(NULL, NA)
```
We can't return `NA` here because `vec_ptype2()` normally returns empty vectors. We also can't return `NULL` because unspecified vectors need to be recognised as logical vectors if they haven't been promoted at the end of the reduction.
```{r}
vec_ptype_finalise(vec_ptype2(NULL, NA))
```
See the output of `vec_ptype_common()` which performs the reduction and finalises the type, ready to be used by the caller:
```{r}
vec_ptype_common(NULL, NULL)
vec_ptype_common(NA, NULL)
```
Note that __partial__ types in vctrs make use of the same mechanism. They are finalised with `vec_ptype_finalise()`.
vctrs/man/faq/internal/setup.Rmd 0000644 0001762 0000144 00000000132 13622451540 016353 0 ustar ligges users
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```
vctrs/man/vec_is_list.Rd 0000644 0001762 0000144 00000001545 13623045211 014762 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/assert.R
\name{vec_is_list}
\alias{vec_is_list}
\title{Is the object a list?}
\usage{
vec_is_list(x)
}
\arguments{
\item{x}{An object.}
}
\description{
\code{vec_is_list()} tests if \code{x} is considered a list in the vctrs sense. It
returns \code{TRUE} if:
\itemize{
\item \code{x} is a bare list with no class.
\item \code{x} is a list explicitly inheriting from \code{"list"} or \code{"vctrs_list_of"}.
\item \code{x} is an S3 list that \code{\link[=vec_is]{vec_is()}} returns \code{TRUE} for. For this to return
\code{TRUE}, the class must implement a \code{\link[=vec_proxy]{vec_proxy()}} method.
}
}
\details{
Notably, data frames and S3 record style classes like POSIXlt are not
considered lists.
}
\examples{
vec_is_list(list())
vec_is_list(list_of(1))
vec_is_list(data.frame())
}
vctrs/man/vctrs-conditions.Rd 0000644 0001762 0000144 00000006655 13622451540 016003 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/conditions.R
\name{vctrs-conditions}
\alias{vctrs-conditions}
\alias{stop_incompatible_type}
\alias{stop_incompatible_cast}
\alias{stop_incompatible_op}
\alias{stop_incompatible_size}
\alias{maybe_lossy_cast}
\alias{allow_lossy_cast}
\title{Custom conditions for vctrs package}
\usage{
stop_incompatible_type(
x,
y,
x_arg = "",
y_arg = "",
details = NULL,
...,
message = NULL,
class = NULL
)
stop_incompatible_cast(
x,
y,
details = NULL,
...,
x_arg = "",
to_arg = "",
message = NULL,
class = NULL
)
stop_incompatible_op(
op,
x,
y,
details = NULL,
...,
message = NULL,
class = NULL
)
stop_incompatible_size(
x,
y,
x_size,
y_size,
x_arg = "",
y_arg = "",
details = NULL,
...,
message = NULL,
class = NULL
)
maybe_lossy_cast(
result,
x,
to,
lossy = NULL,
locations = NULL,
details = NULL,
...,
x_arg = "",
to_arg = "",
message = NULL,
class = NULL,
.deprecation = FALSE
)
allow_lossy_cast(expr, x_ptype = NULL, to_ptype = NULL)
}
\arguments{
\item{x, y}{Vectors}
\item{details}{Any additional human readable details}
\item{..., message, class}{Only use these fields when creating a subclass.}
\item{result}{The result of a potentially lossy cast.}
\item{to}{Type to cast to.}
\item{lossy}{A logical vector indicating which elements of \code{result}
were lossy.
Can also be a single \code{TRUE}, but note that \code{locations} picks up
locations from this vector by default. In this case, supply your
own location vector, possibly empty.}
\item{locations}{An optional integer vector giving the
locations where \code{x} lost information.}
\item{.deprecation}{If \code{TRUE}, the error is downgraded to a
deprecation warning. This is useful for transitioning your class
to a stricter conversion scheme. The warning advises your users
to wrap their code with \code{allow_lossy_cast()}.}
\item{x_ptype, to_ptype}{Suppress only the casting errors where \code{x}
or \code{to} match these \link[=vec_ptype]{prototypes}.}
\item{subclass}{Use if you want to further customise the class}
}
\value{
\verb{stop_incompatible_*()} unconditionally raise an error of class
\code{"vctrs_error_incompatible_*"} and \code{"vctrs_error_incompatible"}.
}
\description{
These functions are called for their side effect of raising
errors and warnings.
These conditions have custom classes and structures to make
testing easier.
}
\section{Lossy cast errors}{
By default, lossy casts are an error. Use \code{allow_lossy_cast()} to
silence these errors and continue with the partial results. In this
case the lost values are typically set to \code{NA} or to a lower value
resolution, depending on the type of cast.
Lossy cast errors are thrown by \code{maybe_lossy_cast()}. Unlike
functions prefixed with \code{stop_}, \code{maybe_lossy_cast()} usually
returns a result. If a lossy cast is detected, it throws an error,
unless it's been wrapped in \code{allow_lossy_cast()}. In that case, it
returns the result silently.
}
\examples{
# Most of the time, `maybe_lossy_cast()` returns its input normally:
maybe_lossy_cast(c("foo", "bar"), NULL, "", lossy = c(FALSE, FALSE))
# If `lossy` has any `TRUE`, an error is thrown:
try(maybe_lossy_cast(c("foo", "bar"), NULL, "", lossy = c(FALSE, TRUE)))
# Unless lossy casts are allowed:
allow_lossy_cast(
maybe_lossy_cast(c("foo", "bar"), NULL, "", lossy = c(FALSE, TRUE))
)
}
\keyword{internal}
vctrs/man/vec_c.Rd 0000644 0001762 0000144 00000005631 13622451540 013543 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/c.R
\name{vec_c}
\alias{vec_c}
\title{Combine many vectors into one vector}
\usage{
vec_c(
...,
.ptype = NULL,
.name_spec = NULL,
.name_repair = c("minimal", "unique", "check_unique", "universal")
)
}
\arguments{
\item{...}{Vectors to coerce.}
\item{.ptype}{If \code{NULL}, the default, the output type is determined by
computing the common type across all elements of \code{...}.
Alternatively, you can supply \code{.ptype} to give the output known type.
If \code{getOption("vctrs.no_guessing")} is \code{TRUE} you must supply this value:
this is a convenient way to make production code demand fixed types.}
\item{.name_spec}{A name specification for combining
inner and outer names. This is relevant for inputs passed with a
name, when these inputs are themselves named, like \code{outer = c(inner = 1)}, or when they have length greater than 1: \code{outer = 1:2}. By default, these cases trigger an error. You can resolve
the error by providing a specification that describes how to
combine the names or the indices of the inner vector with the
name of the input. This specification can be:
\itemize{
\item A function of two arguments. The outer name is passed as a
string to the first argument, and the inner names or positions
are passed as second argument.
\item An anonymous function as a purrr-style formula.
\item A glue specification of the form \code{"{outer}_{inner}"}.
}
See the \link[=name_spec]{name specification topic}.}
\item{.name_repair}{How to repair names, see \code{repair} options in \code{\link[=vec_as_names]{vec_as_names()}}.}
}
\value{
A vector with class given by \code{.ptype}, and length equal to the
sum of the \code{vec_size()} of the contents of \code{...}.
The vector will have names if the individual components have names
(inner names) or if the arguments are named (outer names). If both
inner and outer names are present, an error is thrown unless a
\code{.name_spec} is provided.
}
\description{
Combine all arguments into a new vector of common type.
}
\section{Invariants}{
\itemize{
\item \code{vec_size(vec_c(x, y)) == vec_size(x) + vec_size(y)}
\item \code{vec_ptype(vec_c(x, y)) == vec_ptype_common(x, y)}.
}
}
\examples{
vec_c(FALSE, 1L, 1.5)
vec_c(FALSE, 1L, "x", .ptype = character())
# Date/times --------------------------
c(Sys.Date(), Sys.time())
c(Sys.time(), Sys.Date())
vec_c(Sys.Date(), Sys.time())
vec_c(Sys.time(), Sys.Date())
# Factors -----------------------------
c(factor("a"), factor("b"))
vec_c(factor("a"), factor("b"))
# By default, named inputs must be length 1:
vec_c(name = 1)
try(vec_c(name = 1:3))
# Pass a name specification to work around this:
vec_c(name = 1:3, .name_spec = "{outer}_{inner}")
# See `?name_spec` for more examples of name specifications.
}
\seealso{
\code{\link[=vec_cbind]{vec_cbind()}}/\code{\link[=vec_rbind]{vec_rbind()}} for combining data frames by rows
or columns.
}
vctrs/man/vec_empty.Rd 0000644 0001762 0000144 00000000615 13622451540 014454 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/vctrs-deprecated.R
\name{vec_empty}
\alias{vec_empty}
\title{Is a vector empty}
\usage{
vec_empty(x)
}
\arguments{
\item{x}{An object.}
}
\description{
\Sexpr[results=rd, stage=render]{vctrs:::lifecycle("defunct")}
This function is defunct, please use \code{\link[=vec_is_empty]{vec_is_empty()}}.
}
\keyword{internal}
vctrs/man/internal-faq-ptype2-identity.Rd 0000644 0001762 0000144 00000010213 13623013722 020102 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/faq-internal.R
\name{internal-faq-ptype2-identity}
\alias{internal-faq-ptype2-identity}
\title{Internal FAQ - \code{vec_ptype2()}, \code{NULL}, and unspecified vectors}
\description{
\subsection{Promotion monoid}{
Promotions (i.e. automatic coercions) should always transform inputs to
their richer type to avoid losing values of precision. \code{vec_ptype2()}
returns the \emph{richer} type of two vectors, or throws an incompatible type
error if none of the two vector types include the other. For example,
the richer type of integer and double is the latter because double
covers a larger range of values than integer.
\code{vec_ptype2()} is a \href{https://en.wikipedia.org/wiki/Monoid}{monoid} over
vectors, which in practical terms means that it is a well behaved
operation for
\href{https://purrr.tidyverse.org/reference/reduce.html}{reduction}.
Reduction is an important operation for promotions because that is how
the richer type of multiple elements is computed. As a monoid,
\code{vec_ptype2()} needs an identity element, i.e. a value that doesn’t
change the result of the reduction. vctrs has two identity values,
\code{NULL} and \strong{unspecified} vectors.
}
\subsection{The \code{NULL} identity}{
As an identity element that shouldn’t influence the determination of the
common type of a set of vectors, \code{NULL} is promoted to any type:\if{html}{\out{