首页 > 解决方案 > 从新数据框中按分类变量提取斜率?

问题描述

我有一个数据集,描述了 199 个国家在 38 年(1980 年至 2008 年)期间的 BMI 变化。数据最初是宽格式的,我(以为我)整理了一下:

BMI <- read.csv("Indicator_BMI female ASM.csv", header = TRUE)
BMI2 <- gather(BMI, "year", "BMI", X1980:X2008)
BMI2$year <- as.numeric(BMI2$year)
BMI <- BMI2

直到它以这种格式结束:

Country          Year       BMI
Afghanistan     X1980      20.443
Afghanistan     X1981      20.477      
Afghanistan     X1982      20.523  
...
Albania         X1980      25.174
Albania         X1981      25.191 
.......
Algeria         X1980      20.241
..... 

等等,你明白了..

我要做的是,为每个国家得到 Year 和 BMI 之间关系的斜率的梯度。

首先,我尝试非常简单地一次提取一个国家的斜率:

thefit <- lm(BMI ~ year, subset(BMI, Country == "Albania"))
gradientAlbania <- round(coef(thefit)[2],4)

但是仅 lm 的输出就非常出乎意料(仅分别截取每一年):

Coefficients:
(Intercept)    yearX1981    yearX1982    yearX1983    yearX1984    yearX1985    yearX1986    yearX1987    yearX1988    yearX1989    yearX1990  
   25.17427      0.01661      0.02605      0.04479      0.04932      0.03830      0.03512      0.01491     -0.00462     -0.02057     -0.03550  
  yearX1991    yearX1992    yearX1993    yearX1994    yearX1995    yearX1996    yearX1997    yearX1998    yearX1999    yearX2000    yearX2001  
   -0.12757     -0.20812     -0.23869     -0.23865     -0.23721     -0.20784     -0.20673     -0.17207     -0.11173     -0.04630      0.02905  
  yearX2002    yearX2003    yearX2004    yearX2005    yearX2006    yearX2007    yearX2008  
    0.09655      0.15771      0.22377      0.29098      0.35901      0.41967      0.48299  

我想这与数据框的格式有关(比如我无法摆脱的年份前面的 X..)虽然我成功地为这个数据创建了一个 BMI~year 散点图,但按国家/地区,所以我原则上假设格式应该没问题?

BMI年散点图

我在这里先向您的帮助表示感谢。万一这很重要,稍后我想将斜率函数作为 dplyr group_by 的一部分,但这将在单独的帖子中出现(为了清楚起见,我决定在不同的帖子中分解问题)。

标签: rgradientlm

解决方案


正如@aosmith 提到的,您需要摆脱那些“X”。

这是否对您的数据有效并完成您想要的:

BMI <- read.csv("Indicator_BMI female ASM.csv", header = TRUE)
BMI2 <- gather(BMI, "year", "BMI", X1980:X2008)
BMI2$year <- as.numeric(gsub('X',"",BMI2$year))

# Adapted from "R for Data Science"

country_model <- function(df){
  lm(BMI~year, data = df)
}

BMI2 %>%
  group_by(country) %>% 
  nest() %>% 
  mutate(model = map(data, country_model)) %>% 
  mutate(slope = model[[1]][[1]][[2]])

推荐阅读