我如何创建然后在某些tibble列上应用函数?

时间:2018-06-03 14:06:23

标签: r function apply tidyverse

我正在尝试练习R并且总体上学习更多。我想对每10万人的x犯罪率进行比率。以下是我的数据的负责人。我决定只使用5个最大的城市。

# A tibble: 6 x 13
City       Popula~ `Viol~ `Mur~ `Rap~ `Rap~ Robbe~ `Aggr~ `Prop~ Burgl~ `Larc~ `Moto~ Arson
 <chr>        <dbl>  <dbl> <dbl> <dbl> <lgl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl> <dbl>
1 Abingdon      8186  10.0   0     3.00 NA      1.00   6.00  233    20.0  198    15.0   4.00
2 Alexandria  148519 258     5.00 21.0  NA    118    114    2967   249    2427   291    13.0 
3 Altavista     3486   8.00  0     0    NA      2.00   6.00   56.0   4.00   52.0   0     0   
4 Amherst       2223   2.00  0     2.00 NA      0      0      27.0   6.00   19.0   2.00  0   
5 Appalachia    1728  12.0   0     2.00 NA      2.00   8.00   77.0  25.0    51.0   1.00  0   
6 Ashland       7310  26.0   0     1.00 NA      8.00  17.0   246    14.0   221    11.0   1.00

以下代码是我的尝试。

virginia_crime %>%
 filter(Population > 180000) %>%
 group_by(City) %>%
 summarise(ratio_violent = `Violent
 crime`/(Population/100000),
 ratio_murder = `Murder and
 nonnegligent
 manslaughter`/(Population/100000))

输出结果为:

# A tibble: 5 x 3
City           ratio_violent ratio_murder
<chr>                  <dbl>        <dbl>
1 Chesapeake               320         3.90
2 Newport News             439         8.28
3 Norfolk                  573        11.3 
4 Richmond                 624        17.4 
5 Virginia Beach           162         3.77

我意识到我应该能够创建一个基本上创建速率的函数。有点像...... rate&lt; - (犯罪列/(人口/ 1000)。我是否接近我的想法,或者我应该使用其中一个应用函数(sapply(summarize()))?我觉得这个任务可能会以某种方式自动化,我无法弄明白。会很感激一些见解

2 个答案:

答案 0 :(得分:2)

您可以先收集列(除了城市和人口之外),这样您就可以同时对所有列进行操作:

library(tidyr)

crime_rates <- virginia_crime %>%
  filter(Population > 180000) %>%
  gather(Crime, Number, -City, -Population) %>%
  mutate(Rate = Number / (Population / 100000))

对于每对城市和犯罪,以及人口,数量和费率,最终会有一行。

如果要将其重新变为宽格式,可以使用点差(删除Number列后):

crime_rates %>%
  select(-Number) %>%
  spread(Crime, Rate)

值得注意的是,收集的(整理的)版本仍然非常有用,例如,如果您想要找到每种犯罪率最高的城市(可能在图表中使用):

crime_rates %>%
  group_by(City) %>%
  top_n(1, Rate)

答案 1 :(得分:2)

以下是mutate_at的选项。在OP的代码中,使用了summarise,但它是用&#39; n&#39;来概括一个对象。行到一行。该比率始终不是一行(基于OP的代码,mutate应该用来代替summarise

library(dplyr)
df1 %>% 
   filter(Population > 180000) %>% 
   mutate_at(3:13, funs(./Population/100000))