【发布时间】:2020-03-08 20:13:57
【问题描述】:
我在非常大的数据集(通常包括模型拟合中的几十个变量)上使用 R 中的 GLM 做了大量工作。为了能够在我拟合模型后产生某种图形输出,我发现“准备”我打算拟合的任何变量作为一个因素很有用(那些名字以f_开头的变量)在模型拟合之前。我的意思是:
(i) 因为我在拟合 GLM 之前对每个因子进行了重新排序,以使参考水平等于权重最大的水平,所以我想保留 relevel() 命令之前的水平排序;
(ii) 为了稍后在图表中突出显示参考水平,我喜欢将其记录在一个单独的变量中。
我已经使用内置的mtcars 数据集将这种方法的示例放在一起。
目前我有这个代码:
library(dplyr)
data(mtcars)
# tidy up and make easier to read
df <- mtcars # built in data set
# let's make it a bit easier to follow
df <- df %>%
select(mpg,
f_cylinders = cyl,
c_displacement = disp,
c_hp = hp,
c_final_drive_ratio = drat,
c_weight = wt,
c_qtr_mile_time = qsec,
f_v_or_straight = vs,
f_transmission = am,
f_gears = gear,
f_num_carbs = carb)
df$f_v_or_straight <- ifelse(df$f_v_or_straight == 0, "V", "Straight")
df$f_transmission <- ifelse(df$f_transmission == 0, "Automatic", "Manual")
df$glm_weight <- 1
# organise factors - levels, reference level, weights
my_list <- list()
df$f_cylinders <- as.factor(df$f_cylinders)
my_list$f_cylinders_levels <- levels(df$f_cylinders)
my_list$f_cylinders_weights <- df %>% group_by(f_cylinders) %>% summarise(glm_weight = sum(glm_weight)) %>% ungroup() %>% pull(glm_weight)
my_list$f_cylinders_ref <- "8"
df$f_cylinders <- df$f_cylinders %>% relevel(ref = my_list$f_cylinders_ref)
df$f_v_or_straight <- as.factor(df$f_v_or_straight)
my_list$f_v_or_straight_levels <- levels(df$f_v_or_straight)
my_list$f_v_or_straight_weights <- df %>% group_by(f_v_or_straight) %>% summarise(glm_weight = sum(glm_weight)) %>% ungroup() %>% pull(glm_weight)
my_list$f_v_or_straight_ref <- "V"
df$f_v_or_straight <- df$f_v_or_straight %>% relevel(ref = my_list$f_v_or_straight_ref)
df$f_transmission <- as.factor(df$f_transmission)
my_list$f_transmission_levels <- levels(df$f_transmission)
my_list$f_transmission_weights <- df %>% group_by(f_transmission) %>% summarise(glm_weight = sum(glm_weight)) %>% ungroup() %>% pull(glm_weight)
my_list$f_transmission_ref <- "Automatic"
df$f_transmission <- df$f_transmission %>% relevel(ref = my_list$f_transmission_ref)
df$f_gears <- as.factor(df$f_gears)
my_list$f_gears_levels <- levels(df$f_gears)
my_list$f_gears_weights <- df %>% group_by(f_gears) %>% summarise(glm_weight = sum(glm_weight)) %>% ungroup() %>% pull(glm_weight)
my_list$f_gears_ref <- "3"
df$f_gears <- df$f_gears %>% relevel(ref = my_list$f_gears_ref)
df$f_num_carbs <- as.factor(df$f_num_carbs)
my_list$f_num_carbs_levels <- levels(df$f_num_carbs)
my_list$f_num_carbs_weights <- df %>% group_by(f_num_carbs) %>% summarise(glm_weight = sum(glm_weight)) %>% ungroup() %>% pull(glm_weight)
my_list$f_num_carbs_ref <- "4"
df$f_num_carbs <- df$f_num_carbs %>% relevel(ref = my_list$f_num_carbs_ref)
这段代码运行良好,但是……在实际使用中,我要处理几十个因子变量,而不仅仅是上面的 5 个。所以如果我有 50 个因子变量,我会重复做同样的事情 50 次。我想将此准备工作捆绑到一个函数调用中,基本上是说:
对于名称以f_ 开头的每个字段(即看起来像f_xxx):
把它从
chr/int/whatever 变成一个因子f_xxx;计算体重
f_xxx_weights计算参考水平
f_xxx_ref(不确定如果领先者出现平局怎么办);将当前因子水平存储在
f_xxx_levels中;重新排列因子水平,使
f_xxx_ref成为列表中的第一个。
我在这里问了很多……但是任何能推动我前进的东西都会非常感激。
谢谢。
【问题讨论】:
-
不,你计算重量吗?或者这与最高频率相同?如果是这样,为什么不通过降低频率来重新排序因子水平?
-
在这种情况下,我使用相等的权重,所以我可以使用 summarise(glm_weight = n()) 而不是 summarise(glm_weight = sum(glm_weight)) - 但总的来说我的权重不会平等。