【问题标题】:Data manipulation, kind of downsampling数据操作,一种下采样
【发布时间】:2020-02-21 13:03:55
【问题描述】:

我有一个大的 csv 文件,下面的数据示例。我将使用八支球队的例子来说明。

home_team    away_team      home_score       away_score         year
belgium      france         2                2                  1990
brazil       uruguay        3                1                  1990
italy        belgium        1                2                  1990
sweden       mexico         3                1                  1990

france       chile          3                1                  1991
brazil       england        2                1                  1991
italy        belgium        1                2                  1991
chile        switzerland    2                2                  1991

我的数据运行了很多年。 我想知道每个团队每年的总得分,见下面的例子,

team            total_scores          year
belgium         4                     1990
france          2                     1990
brazil          3                     1990
uruguay         1                     1990
italy           1                     1990
sweden          3                     1990
mexico          1                     1990

france          3                     1991
chile           5                     1991
brazil          2                     1991
england         1                     1991
italy           1                     1991
belgium         2                     1991
switzerland     2                     1991

想法?

【问题讨论】:

  • 你自己尝试过什么?
  • 除了您尝试过的内容之外,了解使用哪种语言会有所帮助——您已经标记了其中的 2 个

标签: python r downsampling


【解决方案1】:

这是使用tidyversedplyrtidyr)的解决方案,特别是来自tidyrpivot 函数...

library(tidyverse)

df %>% pivot_longer(cols = -year,   #splits non-year columns into home/away and type columns
                    names_to = c("homeaway", "type"), 
                    names_sep = "_", 
                    values_to = "value", 
                    values_ptypes = list(value = character())) %>% 
  select(-homeaway) %>%             #remove home/away
  pivot_wider(names_from = "type",  #restore team and score columns (as list columns)
              values_from = "value") %>% 
  unnest(cols = c(team, score)) %>% #unnest the list columns to year, team, score
  group_by(year, team) %>% 
  summarise(total_goals = sum(as.numeric(score)))

# A tibble: 14 x 3
# Groups:   year [2]
    year team        total_goals
   <int> <chr>             <dbl>
 1  1990 belgium               4
 2  1990 brazil                3
 3  1990 france                2
 4  1990 italy                 1
 5  1990 mexico                1
 6  1990 sweden                3
 7  1990 uruguay               1
 8  1991 belgium               2
 9  1991 brazil                2
10  1991 chile                 3
11  1991 england               1
12  1991 france                3
13  1991 italy                 1
14  1991 switzerland           2

【讨论】:

  • 这对我来说看起来过于复杂。来回旋转和取消嵌套。基本上,在pivot_longer() 之后直到group_by() 之前需要完成的所有事情都是必要的,因为第一步不是一个合适的选择。初始数据并不宽,因为同一案例的重复值不会存储在单独的列中,因此不需要进行透视。
【解决方案2】:

这是 R 中的另一种解决方案。

#Packages needed
library(dplyr)
library(magrittr)
library(tidyr)

#Your data
home_team <- c("belgium", "brazil", "italy", "sweden",
               "france", "brazil", "italy", "chile")
away_team <- c("france", "uruguay", "belgium", "mexico",
               "chile", "england", "belgium", "switzerland")
home_score <- c(2,3,1,3,
                3,2,1,2)
away_score <- c(2,1,2,1,
                1,1,2,2)
year <- c(1990, 1990, 1990, 1990,
          1991, 1991, 1991, 1991)

df <- data.frame(home_team, away_team, home_score, away_score, year, stringsAsFactors = FALSE)

df

#   home_team   away_team home_score away_score year
# 1   belgium      france          2          2 1990
# 2    brazil     uruguay          3          1 1990
# 3     italy     belgium          1          2 1990
# 4    sweden      mexico          3          1 1990
# 5    france       chile          3          1 1991
# 6    brazil     england          2          1 1991
# 7     italy     belgium          1          2 1991
# 8     chile switzerland          2          2 1991


#Column names for the new data.frames
my_colnames <- c("team", "score", "year")

#Using select() to create separate home and away datasets
df_home <- df %>% select(matches("home|year")) %>% setNames(my_colnames) %>% mutate(game_where = "home")
df_away <- df %>% select(matches("away|year")) %>% setNames(my_colnames) %>% mutate(game_where = "away")

#rbind()'ing both data.frames
#Grouping the rows together first by the team and then by the year
#Summing up the scores for the aforementioned groupings
#Sorting the newly produced data.frame by year
df_1 <- rbind(df_home, df_away) %>% group_by(team, year) %>% tally(score) %>% arrange(year)

df_1 

 #   team         year     n
 #   <chr>       <dbl> <dbl>
 # 1 belgium      1990     4
 # 2 brazil       1990     3
 # 3 france       1990     2
 # 4 italy        1990     1
 # 5 mexico       1990     1
 # 6 sweden       1990     3
 # 7 uruguay      1990     1
 # 8 belgium      1991     2
 # 9 brazil       1991     2
 #10 chile        1991     3
 #11 england      1991     1
 #12 france       1991     3
 #13 italy        1991     1
 #14 switzerland  1991     2

【讨论】:

    【解决方案3】:

    你可以试试:

    library(dplyr)
    
    setNames(rbind(df[,c(1,3,5)], 
                   setNames(df[,c(2,4,5)], names(df[,c(1,3,5)]))), 
             c("Country", "Goals", "Year")) %>%
      group_by(Year, Country) %>% 
      summarize(Total = sum(Goals))
    #> # A tibble: 14 x 3
    #> # Groups:   Year [2]
    #>     Year Country     Total
    #>    <int> <chr>       <int>
    #>  1  1990 belgium         4
    #>  2  1990 brazil          3
    #>  3  1990 france          2
    #>  4  1990 italy           1
    #>  5  1990 mexico          1
    #>  6  1990 sweden          3
    #>  7  1990 uruguay         1
    #>  8  1991 belgium         2
    #>  9  1991 brazil          2
    #> 10  1991 chile           3
    #> 11  1991 england         1
    #> 12  1991 france          3
    #> 13  1991 italy           1
    #> 14  1991 switzerland     2
    

    reprex package (v0.3.0) 于 2020 年 2 月 21 日创建

    【讨论】:

      【解决方案4】:

      添加仅使用 dplyr 的解决方案。

       library(dplyr)
      
       bind_rows(
         select(df, team = home_team, score = home_score, year),
         select(df, team = away_team, score = away_score, year)
       ) %>% 
         group_by(team, year) %>% 
         summarise(total_scores = sum(score))
      

      【讨论】:

        猜你喜欢
        • 2015-02-20
        • 1970-01-01
        • 1970-01-01
        • 2016-07-06
        • 1970-01-01
        • 1970-01-01
        • 2018-12-04
        • 1970-01-01
        • 2015-03-04
        相关资源
        最近更新 更多