【问题标题】:Transforming/reshaping a dataset : Ranking College football teams for the last 50 years转换/重塑数据集:过去 50 年的大学橄榄球队排名
【发布时间】:2015-11-08 06:56:31
【问题描述】:

我需要一些帮助来转换我的数据集。我将不胜感激任何帮助或反馈。

我有过去 50 年的大学橄榄球分数数据。我目前有一个如图 1 所示的数据框,我需要获得一个类似于图 2 的数据框。我想要获得的数据框需要有一个每年参加的所有球队的串联列表,还有两列分别记录胜负。串联列表必须针对每一年。所以基本上是一个像图 2 一样的数据框,但每年都有单独的数据。

这是获得类似于我在图一中的清理数据帧的代码。

# Make generic data frame and get data

practice = data.frame('a'=character(), 'b'=character(), 'c'= numeric(), 'd'=character(), 'e'= numeric(), 'f'=character())
widths = c(10, 28, 5, 28, 3, 19)
years = 1960:2010
for (i in years){
  football_page = paste('http://homepages.cae.wisc.edu/~dwilson/rsfc/history/howell/cf', i, 'gms.txt',sep = '')
  get_data = read.fwf(football_page, widths)
  practice = rbind(practice, get_data)
}

heading = list('DATE', 'AWAY TEAM', 'AWAY SCORE', 'HOME TEAM', 'HOME SCORE', 'LOCATION')
colnames(practice) = heading


# Fixing season dates

practice = cbind('SEASON'=numeric(nrow(practice)),practice)
fix_date = matrix(0, nrow = nrow(practice))
for (j in 1:nrow(fix_date)){
  fix_date[j,1] = substr(practice[j,2],7,10)
}
fix_date = as.numeric(fix_date)
practice$SEASON = fix_date
for (j in 1:nrow(practice)){
  if (grepl('01/.......', practice[j,2]))
    practice[j,1] = practice[j,1]-1 
}


#fix names

practice[,3]=gsub(' ','',practice[,3])
practice[,5]=gsub(' ','',practice[,5])


#drop location and columns

practice = practice[, -7]
practice = practice[, -2]

数据集称为练习。

【问题讨论】:

  • 有几种方法可以做到这一点。我可能会使用dplyr 并编写一个函数来过滤单个团队(主队或客队)的数据,按年份分组,并计算和总结输赢。您可以 lapply 将该函数用于唯一团队名称的向量,然后将结果列表合并到单个数据框中。你试过什么没用?
  • 感谢您的回复!不幸的是,我只被允许使用来自基本 R 的代码,所以我不能使用 dplyR。我尝试了很多不同的事情,并且只用了一年就得到了正确的结果,但是当我尝试做很多年之后,计算时间就会成倍增长,并给我带来奇怪的结果。你想看代码吗?
  • 你能给我一个你将如何使用 dplyr 的例子吗? @ulfelder
  • 胜负应该比较直接。您基本上只需要添加 winning_teamlosing_team 辅助列并在这些列上创建表,然后进行合并。大概您还有另一个为团队分配索引的数据框。你需要它来创建你的对手栏,
  • 如果我上传数据集,图1中的那个,你能试试吗?我对 R 比较陌生,这绝对是一场斗争。 @RajeshS

标签: regex r transform


【解决方案1】:

如果没有您的数据样本或类似的东西,我无法对其进行彻底测试,但我认为这样就可以了。

# Create a function to get win and loss counts by season for a single team
teamsum <- function(teamname) {
  require(dplyr)
  df <- practice %>%
    # Reduce the data set to games involving a single team
    filter(AWAY TEAM==teamname | HOME TEAM==teamname) %>%
    # Create a 0/1 indicator for whether or not that team won each of those games. Note
    # that ties will get treated as losses here; you could change that with a more
    # complicated set of if/else statements
    mutate(team = teamname,
       win = ifelse((AWAY TEAM==teamname & AWAY SCORE > HOME SCORE) |
        (HOME TEAM==teamname & HOME SCORE > AWAY SCORE), 1, 0)) %>%
    # Group the data by season for the summing to follow
    group_by(SEASON) %>%
    # Reduce the data to a table with counts of wins and losses by season
    summarise(wins = sum(win),
      losses = n() - sum(win)) %>%
    # Add the team name as an id column to that summary table. In dplyr piping, '.' is
    # the object created by the preceding step in the pipeline -- here, that summary
    # table of wins and losses.
    cbind(team = rep(teamname, nrow(.)), .) %>%
  return(df)
}

# Apply that function to a vector of unique team names to make a list with
# tables of win & loss counts by season for each team in the original data.
# This version assumes that every team was the home team at least once.
teamlist <- lapply(unique(practice[,"HOME TEAM"]), teamsum)

# Merge the elements of that list into a single data frame. You could rbind, too.
df <- Reduce(function(...) merge(...), teamlist)

【讨论】:

  • 感谢您的帮助!我能够使用这些列表并将它们绑定到一个大数据框中。
【解决方案2】:

另一个dplyr答案

我使用您的代码获取数据集,然后复制团队列作为重塑数据集的关键,您可能可以使用相同的概念来实现基础 R 中的目标。

library(dplyr)
library(tidyr)

practice_2 <- practice %>%
  mutate(home = `HOME TEAM`,
         away = `AWAY TEAM`) %>% 
  # transform dataset to long format with `tidyr::gather()`
  gather(LOC, TEAM, 6:7) %>% 
  group_by(SEASON, TEAM) %>%
  mutate(won  = ifelse(LOC == "home",
                      as.numeric(`HOME SCORE` >  `AWAY SCORE`),
                      as.numeric(`AWAY SCORE` >  `HOME SCORE`)),
         lost = ifelse(LOC == "home",
                      as.numeric(`HOME SCORE` <= `AWAY SCORE`),
                      as.numeric(`AWAY SCORE` <= `HOME SCORE`)),
         op = ifelse(LOC == "home", `AWAY TEAM`, `HOME TEAM`)) %>% 
  summarise(WINS   = sum(won, na.rm = TRUE),
            LOSSES = sum(lost, na.rm = TRUE),
            OPPONENTS = list(unique(op)))

【讨论】:

  • 非常感谢您的帮助!它让我走上了正轨!
猜你喜欢
  • 2021-09-22
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-19
  • 1970-01-01
  • 2015-08-16
  • 2020-04-30
相关资源
最近更新 更多