【问题标题】:R: Aggregate data but some aggregated observations need to be split upR:汇总数据,但需要拆分一些汇总的观察结果
【发布时间】:2017-09-14 15:30:14
【问题描述】:

我有两个需要合并的数据框。下面是每个组成的示例。这些是学区:第一个是收入,第二个是成绩。


School district     revenue
Richland 1          8702
Richland 2          3749
Richland Board       892
Charleston          6324
Greenville          1245
Greenville Board     371

School district     grade
Richland 1          A
Richland 2          A+
Charleston          B
Greenville          D

目标是合并这两个数据框,并将最终结果汇总到与第二(等级)数据框相同的级别。我不得不做一个数据字典来合并它们,因为每个名称都不同(尽管我在这里删除了它以简化),而且还要处理聚合。我打算按以下方式设置我的字典:

School_dist1    School_dist2
Richland 1      Richland 1
Richland 2      Richland 2
?????           Richland Board
Charleston      Charleston
Greenville      Greenville
Greenville      Greenville Board

然后我会简单地在 school_dist1 列上进行聚合。正如您所看到的,问题在于,虽然格林维尔委员会可以简单地聚合到格林维尔,但里奇兰委员会需要在两个里奇兰委员会之间(平均分配)。

我尝试使用我能想到的每一个可能的关键字来搜索解决方案,但由于问题的怪异性质,我找不到任何东西。它的要点是,我需要聚合数据,但需要拆分一些观察结果,然后在它们被聚合到的其他观察值之间共享。

有没有办法做到这一点?我说得有道理吗?我完全被这个难住了。

【问题讨论】:

  • 如果您显示您的尝试代码会很有帮助
  • 我真的不知道从哪里开始。我什至不知道这是否可能,这就是我在这里的原因。我通常可以在这里搜索并在途中弄清楚,但我找不到任何人询问如何做类似的事情。
  • 听起来您可能需要使用 dplyr 包中的连接函数之一。您可能想要的是full_join。这里有一个很好的描述:r4ds.had.co.nz/relational-data.html#introduction-7

标签: r merge dplyr aggregate plyr


【解决方案1】:

这是回家的路很长,但它会带你到那里......

# your data, dont use spaces in column names
df1 <- read.table(text = "School_district     revenue
Richland_1          8702
                 Richland_2          3749
                 Richland_Board       892
                 Charleston          6324
                 Greenville          1245
                 Greenville_Board     371", header = T)

df2 <- read.table(text = "School_district     grade
Richland_1          A
Richland_2          A+
Charleston          B
Greenville          D", header = T)

library(tidyverse)
# split df1 with boards and non-boards into separate dfs
boards <- dplyr::filter(df1, grepl("Board", df1$School_district)) %>%
    dplyr::mutate(School_district = gsub("_Board", "", School_district))
df1 <-  dplyr::filter(df1, !grepl("Board", df1$School_district))

# look up how many times a certain school district appears in df1
boards$num_splits <- map_int(boards$School_district,
                             ~ grep(., df1$School_district) %>% length)
# add new column for revenue divided by number of appearances
boards <- transmute(boards,
                    match_name = School_district,
                    add_value = revenue / num_splits)

# if I knew how to use fuzzy_join you could probably drop this part
df1$match_name <- gsub("_.*", "", df1$School_district)

full_join(df1, boards) %>%
    rowwise() %>%
    mutate(new_revenue = sum(revenue, add_value, na.rm = T)) %>%
    select(-match_name) %>%
    full_join(df2)

# A tibble: 4 × 5
School_district revenue add_value new_revenue  grade
<chr>   <int>     <dbl>       <dbl> <fctr>
1      Richland_1    8702       446        9148      A
2      Richland_2    3749       446        4195     A+
3      Charleston    6324        NA        6324      B
4      Greenville    1245       371        1616      D

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-26
    • 2020-03-27
    • 1970-01-01
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    • 2020-03-16
    • 1970-01-01
    相关资源
    最近更新 更多