处理“调查”包中的零细胞计数

问题描述 投票:0回答:1

[编辑以包括较小的可重现示例]

目标

我正在学习 R

survey
包来获取双向 58 x 4 列联表的单元格比例(特别是行百分比)和置信区间,并考虑复杂的样本设计进行方差估计。行中包含 58 个加利福尼亚州县,列中包含四个类别(异性恋、男同性恋/女同性恋、双性恋和其他)的“性取向”变量。

问题

问题是几个小县的细胞计数为零。当我尝试使用

svyby
方法获取表格时,出现错误“数据长度不是行数的因数或倍数。”

这是一个可重现的示例:

# Set the number of trials and the probabilities for each outcome
set.seed(16)
probs <- c(.94, .03, .02, .01)
n <- 10000

#Tables with 0s

#Create df
sogi <- data.frame(t(rmultinom(n, 1, prob = probs)))
names(sogi) <- c("straight","gay","bisexual","other")
df_sogi <- sogi %>% mutate(sexual_orientation = 
  as.factor(case_when(
    straight %in% 1 ~ 0,
    gay %in% 1 ~ 1,
    bisexual %in% 1 ~ 2,
    other %in% 1 ~ 3))) %>%
  mutate(pw = runif(n, 0.2, 3.5)) %>%
  mutate(county = as.factor(rep(LETTERS[1:10], each = n/length(LETTERS[1:10])))) %>%
  mutate(ind = row_number()) %>%
  select(ind, county, sexual_orientation, pw) 

#Check raw counts
table(df_sogi$county, df_sogi$sexual_orientation)

#Make survey design and survey design replicate objects
df_svy_z1 <- svydesign(id=~ind, data = df_sogi, weights = ~pw)

#Estimate cell means
svyby(formula = ~county, by = ~sexual_orientation, design = df_svy_z1, FUN = svymean)


#Modify table to put in zeroes
df_sogi$sexual_orientation <- ifelse(df_sogi$county %in% c("G","I") & df_sogi$sexual_orientation==3, 
       df_sogi$sexual_orientation == 0, df_sogi$sexual_orientation)

Check raw counts
table(df_sogi$county, df_sogi$sexual_orientation)

df_svy_z2 <- svydesign(id=~ind, data = df_sogi, weights = ~pw)
svyby(~factor(county), ~factor(sexual_orientation), df_svy_z2, svymean)

r sparse-matrix survey divide-by-zero
1个回答
0
投票

你的问题是

county
不是一个因素。当调用 svymean 时,它会分别
转换为每个子集的因子,但由于该调用仅针对子集,因此因子级别只是子集中存在的级别。

因子的

全部要点是它们知道它们可能的水平是什么,当以这种方式进行转换时,你会失去这整点。您要么必须提前转换

df_svy_z2<-update(df_svy_z1, countyf=factor(county)) svyby(~factor(countyf), ~factor(sexual_orientation), df_svy_z2, svymean)
或在调用中明确列出可能的级别 

factor()


svyby(~factor(county,levels=LETTERS[1:10]), ~factor(sexual_orientation), df_svy_z2, svymean)
这通常不是问题,因为读入数据时会自动完成因子转换;很少有人的数据集中有字符串。自从更改为 R 默认值 

stringsAsFactors=FALSE

 以来,人们越来越常见地拥有本应是因子但仅表示为字符串的变量。

这个问题非常常见,以至于帮助页面上有一个注释

svyby


该函数的工作原理是进行大量 FUN(formula,subset(design, by==i)) 形式的调用,其中公式在每个子集中重新计算,因此在公式中使用数据依赖项是不明智的。特别是, svyby(~factor(a), ~b, design=d, svymean) 将创建因子变量,其级别仅为每个子集中存在的那些值。如果 a 是字符变量,则 svyby(~a, ~b, design=d, svymean) 隐式创建因子变量,因此存在相同的问题。要么使用 update.survey.design 将变量添加到设计对象,要么在对因子的调用中显式指定级别。 stringsAsFactors=TRUE 选项将所有字符变量转换为因子,这可能会很慢,如果您在必要时有预定义因子,请将其设置为 FALSE。

正如注释所说,第三种选择是

svyby(~factor(county), ~factor(sexual_orientation), df_svy_z2, svymean, stringsAsFactors=TRUE)
但这不是最佳实践,因为它将 

all 字符串转换为因子,并且它假设您希望将数据中存在的因子级别集传递给 svyby

 并按默认顺序。

© www.soinside.com 2019 - 2024. All rights reserved.