【问题标题】:R Capturing regression slopes by group in a dataframeR在数据框中按组捕获回归斜率
【发布时间】:2019-06-15 03:35:19
【问题描述】:

我的数据框包含 3 个财政年度(2013 财年、2014 财年和 2015 财年)调查中提出的不同问题的分数。 结果由Region呈现。

这是实际数据框的样本的样子,每个区域有两个问题,在不同年份提出。

testdf=data.frame(FY=c("FY13","FY14","FY15","FY14","FY15","FY13","FY14","FY15","FY13","FY15","FY13","FY14","FY15","FY13","FY14","FY15"),
              Region=c(rep("AFRICA",5),rep("ASIA",5),rep("AMERICA",6)),
              QST=c(rep("Q2",3),rep("Q5",2),rep("Q2",3),rep("Q5",2),rep("Q2",3),rep("Q5",3)),
              Very.Satisfied=runif(16,min = 0, max=1),
              Total.Very.Satisfied=floor(runif(16,min=10,max=120)))

我的目标

对于每个地区,我的目标是确定在这 3 年的时间范围内哪个问题经历了最显着的向上演变。为了测量显着的向上运动,我决定使用回归的斜率作为参数。

在 3 年的时间范围内,一个区域内向上演变最显着的问题将是具有最陡正斜率的问题。

使用这个逻辑,我决定做以下事情-

1) 对于Region 和QST 的每个组合,我运行lm 函数。

2) 我提取每个组合的斜率,并将其存储为单独的变量。然后对于每个区域,我过滤掉具有最大斜率值的问题。

我的尝试

这是我解决这个问题的尝试。

test_final=testdf %>%   
group_by(Region,QST) %>% 
map(~lm(FY ~ Very.Satisfied, data = .)) %>%
map_df(tidy) %>%
filter(term == 'circumference') %>%
select(estimate) %>% 
summarise(Value = max(estimate))

但是,当我运行它时,我收到一条错误消息,指出该对象 FY 没找到。

附加要求

另外,我希望这仅适用于具有至少连续 2 年数据进行比较的问题。但我无法弄清楚如何将这种情况考虑到我的代码中。

对此的任何帮助将不胜感激。

【问题讨论】:

  • 这里有几个问题,包括:首先,我认为FY 应该是会计年度。但是 R 不知道它是一个日期,所以它会认为你想要回归一个数值变量的多值因子。它不会那样。您需要将 FY 转换为数值,例如年份。这是你的意图吗?此外,如果您想要对满意度随时间变化的线性近似值,您应该以相反的方式进行回归 lm(satisfaction~date),这就是您所追求的吗?
  • 是的,这就是我要找的。​​span>

标签: r lm broom


【解决方案1】:

这没有做“至少连续两年”部分,但它做了“得到斜率最大的问题”部分:

library(dplyr)
test_final = testdf %>%
  mutate(FY.num = as.numeric(gsub("FY", "", FY))) %>%
  group_by(Region, QST) %>%
  mutate(lm_slope = lm(Very.Satisfied ~ FY.num)$coefficients[["FY.num"]]) %>%
  ungroup() %>%
  group_by(Region) %>%
  filter(lm_slope == max(lm_slope))

【讨论】:

    【解决方案2】:

    这是一个类似的版本,按组大小/连续性过滤(在您发布时已经写好了,所以我想我还是继续吧)。

    library(tidyverse)
    set.seed(42)
    testdf=data.frame(FY=c("FY13","FY14","FY15","FY14","FY15","FY13","FY14","FY15","FY13","FY15","FY13","FY14","FY15","FY13","FY14","FY15"),
                      Region=c(rep("AFRICA",5),rep("ASIA",5),rep("AMERICA",6)),
                      QST=c(rep("Q2",3),rep("Q5",2),rep("Q2",3),rep("Q5",2),rep("Q2",3),rep("Q5",3)),
                      Very.Satisfied=runif(16,min = 0, max=1),
                      Total.Very.Satisfied=floor(runif(16,min=10,max=120)))
    
    test_final <- testdf %>%   
      group_by(Region,QST) %>% # group by region
      mutate(numdate = as.numeric(str_remove(FY, "FY"))) %>% 
      filter(n() >= 2 & max(diff(numdate)) < 2) %>% # filter out singleton groups
      mutate(slopes = coef(lm(Very.Satisfied~numdate))[2])
    test_final %>% select(Region, QST, slopes)
    #> # A tibble: 14 x 3
    #> # Groups:   Region, QST [5]
    #>    Region  QST   slopes
    #>    <fct>   <fct>  <dbl>
    #>  1 AFRICA  Q2    -0.314
    #>  2 AFRICA  Q2    -0.314
    #>  3 AFRICA  Q2    -0.314
    #>  4 AFRICA  Q5    -0.189
    #>  5 AFRICA  Q5    -0.189
    #>  6 ASIA    Q2    -0.192
    #>  7 ASIA    Q2    -0.192
    #>  8 ASIA    Q2    -0.192
    #>  9 AMERICA Q2     0.238
    #> 10 AMERICA Q2     0.238
    #> 11 AMERICA Q2     0.238
    #> 12 AMERICA Q5     0.342
    #> 13 AMERICA Q5     0.342
    #> 14 AMERICA Q5     0.342
    
    test_final %>% group_by(Region) %>% 
      summarise(Value = max(slopes),
                Top_Question = QST[which.max(slopes)])
    #> # A tibble: 3 x 3
    #>   Region   Value Top_Question
    #>   <fct>    <dbl> <fct>       
    #> 1 AFRICA  -0.189 Q5          
    #> 2 AMERICA  0.342 Q5          
    #> 3 ASIA    -0.192 Q2
    

    由reprex package (v0.2.1) 于 2019-01-21 创建

    【讨论】:

    • 比我的优雅得多——非常好!
    • @A.S.K.你的几乎一模一样!你先发布了,所以感谢你
    • 非常感谢你们。我需要对您的代码进行哪些修改以显示前 3 个而不是仅显示最大值?
    猜你喜欢
    • 2019-09-28
    • 2013-02-05
    • 1970-01-01
    • 2018-02-25
    • 2014-02-15
    • 1970-01-01
    • 1970-01-01
    • 2021-07-28
    • 1970-01-01
    相关资源
    最近更新 更多