将Survey List对象转换为数据框,并将字符串列拆分为多列

时间:2019-10-21 14:47:03

标签: r split tidyverse stringr survey

我正在使用Survey软件包进行调查分析。我正在从数据集中制作4向列联表。我的数据集如下(虚拟数据):

df <- data.frame(
         v_1 = c(2, NA, 2, 1, 1, NA, 2, 1, 2, NA, 1, 2, 1, 2, 2),
         v_2 = c(NA, NA, 1, NA, 1, NA, 2, 1, 3, NA, 1, NA, 1,2, NA),
         v_3 = c(1, NA, NA, 1, 2,2, NA, NA, 2, NA, 2, NA, NA, NA, 2),
         v_4 = c(NA, NA, NA, 1, 2, NA, NA, 1, 2, NA, 2, NA, 1, 2, 1),
      weight = c(526, 1203, 1124, 526, 533, 1064, 564, 1124, 412, 1064, 581,
                 1064, 564, 999, 420),
       v_5 = c(2, NA, 2, 1, 1, NA, 2, 1, 2, NA, 1, 2, 1, 2, 2)
)

计算完每个类别的频率以及标准误差后,我想将其转换为数据帧并运行求和过滤器等,这仅是因为baseR的data.frame()在起作用。转换并设置索引后,我想通过匹配模式将第一列分为多列。

library(tidyverse)
library(survey) 

ds <- svydesign(ids=~0,data=df, weights=~weight)

#frequencies for each category as well as standard errors
# convert survey list into dataframe
df <- svytotal(~interaction(v_1, v_2, v_3,v_4), ds , na.rm = TRUE)

# convert to dataframe and reset index
dt <- as.data.frame(df, cut.names)
dt <- data.frame(dt , fix.empty.names = TRUE)

输出

                                        total  SE
interaction(v_1, v_2, v_3, v_4)1.1.1.1     0   0
interaction(v_1, v_2, v_3, v_4)2.1.1.1     0   0
interaction(v_1, v_2, v_3, v_4)1.2.1.1     0   0
interaction(v_1, v_2, v_3, v_4)2.2.1.1     0   0
interaction(v_1, v_2, v_3, v_4)1.3.1.1     0   0
interaction(v_1, v_2, v_3, v_4)2.3.1.1     0   0
interaction(v_1, v_2, v_3, v_4)1.1.2.1     0   0
interaction(v_1, v_2, v_3, v_4)2.1.2.1     0   0
interaction(v_1, v_2, v_3, v_4)1.2.2.1     0   0
interaction(v_1, v_2, v_3, v_4)2.2.2.1     0   0

我需要提取v_1,v_2,v_3,v_4作为变量名,并提取1.1.1.1以获取(v_1, v_2, v_3, v_4)1.1.1.1形式的对应值

v_1  v_2  v_3  v_4
1    1     1    1

期望输出

#only for v_1 :v_3
         v_1        v_2       v_3 total  SE
1          1         1         1     0   0
2          2         1         1     0   0
3          1         2         1     0   0
4          2         2         1     0   0
5          1         3         1     0   0
6          2         3         1     0   0
7          1         1         2     0   0

2 个答案:

答案 0 :(得分:1)

我们可以将extract中的tidyr与适当的regex一起使用

library(tidyverse)

dt %>%
  rownames_to_column() %>%
  extract(rowname, into = paste0("v_", 1:4), 
          regex  = ".*\\)(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)")

#   v_1 v_2 v_3 v_4 total  SE
#1    1   1   1   1     0   0
#2    2   1   1   1     0   0
#3    1   2   1   1     0   0
#4    2   2   1   1     0   0
#5    1   3   1   1     0   0
#6    2   3   1   1     0   0
#7    1   1   2   1     0   0
#8    2   1   2   1     0   0
#9    1   2   2   1     0   0
#10   2   2   2   1     0   0
#11   1   3   2   1     0   0
#12   2   3   2   1     0   0
#13   1   1   1   2     0   0
#14   2   1   1   2     0   0
#15   1   2   1   2     0   0
#16   2   2   1   2     0   0
#17   1   3   1   2     0   0
#18   2   3   1   2     0   0
#19   1   1   2   2  1114 760
#20   2   1   2   2     0   0
#21   1   2   2   2     0   0
#22   2   2   2   2     0   0
#23   1   3   2   2     0   0
#24   2   3   2   2   412 412

答案 1 :(得分:1)

如果不想使用零,请删除drop.empty.groups参数

ds <- update( ds , one = 1 )
res <- svyby( ~ one , ~  v_1 + v_2 + v_3 + v_4 , ds , svytotal , drop.empty.groups = FALSE )
res

为您提供想要的东西。可能还有其他格式

res <- data.frame( res )
rownames( res ) <- NULL
res