【问题标题】:Count Distinct Restaurants by Zip Code in R在 R 中按邮政编码计算不同的餐厅
【发布时间】:2016-01-13 06:25:51
【问题描述】:

我有一个数据框,其中包含每个美国邮政编码以及位于该邮政编码内的所有快餐店的平均工资。这是该数据框的示例:

Row_NUM ZIP   MEDIAN RESTAURANT
26800   1001  56663  McDonald's
33161   1007  79076  McDonald's
23706   1008  63980  McDonald's
23709   1008  63980  McDonald's
30007   1008  63980  Taco Bell
30008   1008  63980  McDonald's
30009   1011  63476  McDonald's
24429   1013  36578  McDonald's
15323   1020  50058  KFC
29196   1020  50058  McDonald's
33127   1020  50058  McDonald's
39362   1020  50058  Wendy's
44914   1020  50058  Taco Bell
2542    1027  58573  Burger King 
35242   1027  58573  McDonald's

我想做两件事。 首先,我想创建一个新的数据框,其中只有唯一的邮政编码、该邮政编码的工资中位数以及该邮政编码中的餐馆总数。所以,对于这个数据框示例:

ZIP    MEDIAN  TOTAL_RESTAURANTS
1001   56663   1
1007   79076   1
1008   63980   4

其次,我想创建一个数据框,其中只有唯一的邮政编码和一列,其中包含每种快餐店的总数。所以对于这个数据框示例:

ZIP    MEDIAN  TOTAL_MCDONALDS  TOTAL_TACOBELL  TOTAL_KFC
1001   56663   1                0               0
1007   79076   1                0               0
1008   63980   3                1               0

我认为下面的代码可以工作,但它只给了我邮政编码和总餐厅,我不知道如何修改它以包含其他三列。

df <- ddply(df,~ZIP, summarise,TOTAL_RESTAURANTS=length(RESTAURANT))

任何帮助将不胜感激。

编辑:这是我在数据框中使用的数据类型。

    str(df)
    data.frame':    50002 obs. of  3 variables:
 $ ZIP       : int  44126 24014 77011 2190 48509 21061 43213 70130 31907 19422 ...
 $ MEDIAN    : int  54496 50175 27113 74205 50895 62408 36734 47591 38710 103683 ...
 $ RESTAURANT: Factor w/ 10 levels "McDonald's","Burger King",..: 2 2 2 2 2 2 2 2 2 2 ...

这是我的会话信息:

    R version 3.2.2 (2015-08-14)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: OS X 10.11 (El Capitan)

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] graphics  grDevices utils     datasets  grid      stats     methods   base     

other attached packages:
 [1] lubridate_1.3.3 extrafont_0.17  jsonlite_0.9.16 dplyr_0.4.2     tidyr_0.2.0     tableplot_0.3-5 reshape2_1.4.1  RCurl_1.95-4.7 
 [9] bitops_1.0-6    gplots_2.17.0   ggthemes_2.2.1  ggplot2_1.0.1  

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.0        Rttf2pt1_1.3.3     magrittr_1.5       MASS_7.3-43        munsell_0.4.2      colorspace_1.2-6   R6_2.1.1          
 [8] stringr_1.0.0      plyr_1.8.3         caTools_1.17.1     tools_3.2.2        parallel_3.2.2     gtable_0.1.2       KernSmooth_2.23-15
[15] DBI_0.3.1          extrafontdb_1.0    gtools_3.5.0       lazyeval_0.1.10    assertthat_0.1     digest_0.6.8       memoise_0.2.1     
[22] labeling_0.3       gdata_2.17.0       stringi_0.5-5      scales_0.3.0       proto_0.3-10 

【问题讨论】:

    标签: r


    【解决方案1】:

    Uisng dplyrreshape2,这是一种方法。既然要通过ZIP对数据进行汇总,可以使用变量对数据进行分组。我不清楚的一件事是每个 ZIP 的 MEDIAN 值是否相同。在这里,我假设您可能有不同的值。因此,我使用了median()。使用n(),您可以了解目前有多少家快餐店。

    summarize(group_by(mydf, ZIP), mid = median(MEDIAN), total = n())
    
    #If you have an identical MEDIAN for each ZIP, you could do;
    summarize(group_by(mydf, ZIP), mid = first(MEDIAN), total = n())
    
    #    ZIP   mid total
    #  (int) (dbl) (int)
    #1  1001 56663     1
    #2  1007 79076     1
    #3  1008 63980     4
    #4  1011 63476     1
    #5  1013 36578     1
    #6  1020 50058     5
    #7  1027 58573     2
    

    对于第二部分,您可以使用dcast()。您想按快餐店的类型查看快餐店的数量。通过ZIPMEDIAN 的组合,您要求R 检查存在多少家商店(RESTAURANT)。

    dcast(mydf, ZIP + MEDIAN ~ RESTAURANT, length, value.var = "RESTAURANT")
    
    #   ZIP MEDIAN BurgerKing KFC McDonald's TacoBell Wendy's
    #1 1001  56663          0   0          1        0       0
    #2 1007  79076          0   0          1        0       0
    #3 1008  63980          0   0          3        1       0
    #4 1011  63476          0   0          1        0       0
    #5 1013  36578          0   0          1        0       0
    #6 1020  50058          0   1          2        1       1
    #7 1027  58573          1   0          1        0       0
    

    如果您使用data.table,您可以执行以下操作。

    library(data.table)
    setDT(mydf)[, list(mid = first(MEDIAN), total = .N), by = ZIP][]
    # If you calculate median
    setDT(mydf)[, list(mid = as.double(median(MEDIAN)), total = .N), by = ZIP][]
    
    dcast(setDT(mydf), ZIP + MEDIAN ~ RESTAURANT, fun = length, value.var = "RESTAURANT")
    

    数据

    mydf <-structure(list(Row_NUM = c(26800L, 33161L, 23706L, 23709L, 30007L, 
    30008L, 30009L, 24429L, 15323L, 29196L, 33127L, 39362L, 44914L, 
    2542L, 35242L), ZIP = c(1001L, 1007L, 1008L, 1008L, 1008L, 1008L, 
    1011L, 1013L, 1020L, 1020L, 1020L, 1020L, 1020L, 1027L, 1027L
    ), MEDIAN = c(56663L, 79076L, 63980L, 63980L, 63980L, 63980L, 
    63476L, 36578L, 50058L, 50058L, 50058L, 50058L, 50058L, 58573L, 
    58573L), RESTAURANT = structure(c(3L, 3L, 3L, 3L, 4L, 3L, 3L, 
    3L, 2L, 3L, 3L, 5L, 4L, 1L, 3L), .Label = c("BurgerKing", "KFC", 
    "McDonald's", "TacoBell", "Wendy's"), class = "factor")), .Names = c("Row_NUM", 
    "ZIP", "MEDIAN", "RESTAURANT"), class = "data.frame", row.names = c(NA, 
    -15L))
    

    【讨论】:

    • @Spencer 您可能想阅读this question。您要确保先上传 plyr,然后再上传 dplyr。在您的情况下,情况可能并非如此。
    • 所以当我运行汇总代码时,它给了我以下错误:Error in n() : This function should not be called directly
    • @jazzurro 好的,按照您发布的链接解决了该错误,但产生了一个新错误:Error: loss of precision when attempting to convert a numeric to an integer 我还编辑了帖子以显示我正在处理的数据类型。
    • @Spencer mydf 包含 ZIP 和 MEDIAN 作为整数,这可能与您所拥有的相同。我无法重现我这边的错误消息。
    • @Jazzurro 您提供的 mid = first(MEDIAN) 选项有效。非常感谢!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-25
    • 1970-01-01
    相关资源
    最近更新 更多