Jリーグ;J1チーム総年俸と順位の関係

データが取得可能な2002年から2011年までのチーム総年俸と順位をプロットしてみる

初期設定

library(ggplot2, quietly = TRUE)
library(splines, quietly = TRUE)
library(xtable, quietly = TRUE)

関数定義

# 取得可能な年一覧を取得
get.years <- function() {
    first.url <- "http://jsalary.wiki.fc2.com/wiki/%E3%83%81%E3%83%BC%E3%83%A0%E4%B8%80%E8%A6%A7"
    base.url <- "http://jsalary.wiki.fc2.com/"
    first.html <- readLines(con = first.url, n = -1L, warn = FALSE)
    year.line <- first.html[grep("^<h2 id=.*■", first.html)]
    year.links <- sapply(strsplit(year.line, "■"), function(x) {
        return(substring(x[3], 10, nchar(x[3]) - 2))
    })
    names(year.links) <- sapply(strsplit(year.line, "■"), function(x) {
        x[2]
    })
    return(year.links)
}

# その年のチーム名一覧取得
get.teams <- function(url.str) {
    base.url <- "http://jsalary.wiki.fc2.com"
    team.html <- readLines(con = url.str, n = -1L, warn = FALSE)
    team.line <- team.html[grep("^<h3 id=", team.html)]
    team.links <- sapply(strsplit(team.line, "\\\""), function(x) {
        paste(base.url, x[6], sep = "")
    })
    names(team.links) <- sapply(strsplit(team.line, "\\\""), function(x) {
        substring(x[4], 6, 100)
    })
    return(team.links)
}

# そのチームのその年の年俸総額取得
get.salary <- function(url.str) {
    salary.html <- readLines(con = url.str, n = -1L, warn = FALSE)
    salary.line <- salary.html[grep("万円{0,1}</td>", salary.html)]
    if (length(salary.line) > 0) {

    } else {
        salary.line.plus.idx <- grep("\\s*</tr>", salary.html)
        salary.line <- salary.html[salary.line.plus.idx - 1]
    }
    salary.org <- sapply(strsplit(salary.line, "</*td>"), function(x) {
        x[2]
    })
    return(ifelse(sum(as.integer(salary.org), na.rm = TRUE) > 0, sum(as.integer(salary.org), 
        na.rm = TRUE), sum(as.integer(apply(matrix(salary.org), 1, nkf)))))
}

# 全角数字→半角数字へ変換
nkf <- function(num.str = "3000") {
    chars <- strsplit(num.str, "")[[1]]
    ret.num <- paste(apply(matrix(chars), 1, twobyte2onebyte), sep = "", collapse = "")
    return(ifelse(ret.num == "", 0, ret.num))
}

# 2byte-->1byte
twobyte2onebyte <- function(x = "3") {
    switch(x, 0 = return("0"), 1 = return("1"), 2 = return("2"), 3 = return("3"), 
        4 = return("4"), 5 = return("5"), 6 = return("6"), 7 = return("7"), 
        8 = return("8"), 9 = return("9"), return(""))
}

# 年間総合順位取得
get.ranks <- function(url.str) {
    ranks.html <- readLines(con = url.str, n = -1L, warn = FALSE)
    if (length(grep("年間総合順位", ranks.html)) > 0) {
        # 2シーズン制
        ranks.line.idx <- grep("^<td align=\"left\">.*</td>", ranks.html)[grep("^<td align=\"left\">.*</td>", 
            ranks.html) > grep("年間総合順位</span></h4>", ranks.html)]
        ranks.line <- ranks.html[ranks.line.idx]
        rank.nums <- ranks.html[ranks.line.idx - 1]
        ranking <- sapply(strsplit(ranks.html[ranks.line.idx], "(>|<)"), function(x) {
            x[3]
        })
        names(ranking) <- sapply(strsplit(ranks.html[ranks.line.idx - 1], "</*b>"), 
            function(x) {
                as.integer(x[2])
            })
        # 順位が空白の場合の特例
        names(ranking)[is.na(names(ranking))] <- 1:length(ranking)
    } else {
        # 1シーズン制
        ranks.line.idx <- grep("^<td align=\"left\">.+</td>", ranks.html)
        ranks.line <- ranks.html[ranks.line.idx]
        rank.nums <- ranks.html[ranks.line.idx - 1]
        ranking <- sapply(strsplit(ranks.html[ranks.line.idx], "(>|<)"), function(x) {
            x[3]
        })
        names(ranking) <- sapply(strsplit(ranks.html[ranks.line.idx - 1], "</*b>"), 
            function(x) {
                as.integer(x[2])
            })
    }
    if (length(which(ranking != "") > 0)) {
        return(ranking[which(ranking != "")])
    } else {
        return(ranking)
    }

}

ここからメイン

base.url <- "http://jsalary.wiki.fc2.com/"
year.links <- get.years()
for (i in 1:length(year.links)) {
    url.str <- paste(base.url, year.links[i], sep = "")
    team.links <- get.teams(url.str)
    team.ranks <- get.ranks(paste("http://ja.wikipedia.org/wiki/", names(year.links[i]), 
        "のJリーグ", sep = ""))
    team.rank.sal <- matrix(data = NA, ncol = 2, nrow = length(team.links))
    colnames(team.rank.sal) <- c("salary", "ranking")
    rownames(team.rank.sal) <- names(team.links)
    for (j in 1:length(team.links)) {
        salary <- get.salary(team.links[j])
        ranking <- as.integer(names(team.ranks[grep(names(team.links)[j], team.ranks)]))
        if (length(ranking) < 1) {
            if (names(team.links[j]) == "浦和レッドダイヤモンズ") {
                ranking <- as.integer(names(team.ranks[grep("浦和レッズ", 
                  team.ranks)]))
            } else if (names(team.links[j]) == "浦和レッズ") {
                ranking <- as.integer(names(team.ranks[grep("浦和レッドダイヤモンズ", 
                  team.ranks)]))
            } else if (names(team.links[j]) == "ジェフユナイテッド千葉") {
                ranking <- as.integer(names(team.ranks[grep("ジェフユナイテッド市原", 
                  team.ranks)]))
            } else if (names(team.links[j]) == "ジェフユナイテッド市原") {
                ranking <- as.integer(names(team.ranks[grep("ジェフユナイテッド千葉", 
                  team.ranks)]))
            } else if (names(team.links[j]) == "ジェフユナイテッド市原・千葉") {
                ranking <- as.integer(names(team.ranks[grep("ジェフユナイテッド千葉", 
                  team.ranks)]))
            }
        }
        team.rank.sal[j, 1] <- salary
        team.rank.sal[j, 2] <- ranking
    }
    team.rank.sal <- as.data.frame(team.rank.sal)
    team.rank.sal <- team.rank.sal[order(team.rank.sal$salary, decreasing = TRUE), 
        ]
    # plot(team.rank.sal, ylim=c(nrow(team.rank.sal),1),
    # main=names(year.links[i]))
    # abline(lm(team.rank.sal$rank~team.rank.sal$salary),col='red') print('')

    # ggplot2だとうまくいかなかったのでしかたなくデフォルトplotを使用
    p <- qplot(x = salary, y = ranking, data = team.rank.sal, geom = c("point", 
        "smooth"), method = "lm", ylim = c(nrow(team.rank.sal), 1), main = names(year.links[i]))
    print(p)
    cat(paste("<H2>", names(year.links[i]), "のデータ</H2><br>", sep = ""))
    print(xtable(team.rank.sal), type = "html")
}

2002年のデータ


<!– html table generated in R 2.15.1 by xtable 1.7-0 package –>

salary ranking
横浜F・マリノス 79130 2
鹿島アントラーズ 77230 4
ジュビロ磐田 73680 1
名古屋グランパスエイト 68930 6
柏レイソル 68630 12
清水エスパルス 64820 8
ガンバ大阪 62900 3
ヴィッセル神戸 56160 14
ジェフユナイテッド市原 53510 7
京都パープルサンガ 49890 5
浦和レッドダイヤモンズ 44780 11
FC東京 43800 9
東京ヴェルディ 38620 10
ベガルタ仙台 37170 13
コンサドーレ札幌 34450 16
サンフレッチェ広島 31440 15

plot of chunk main

2003年のデータ


<!– html table generated in R 2.15.1 by xtable 1.7-0 package –>

salary ranking
鹿島アントラーズ 89560 5
ガンバ大阪 71050 10
ジュビロ磐田 69870 2
清水エスパルス 69200 11
名古屋グランパスエイト 67111 7
浦和レッドダイヤモンズ 58261 6
横浜F・マリノス 56080 1
柏レイソル 54600 12
セレッソ大阪 53640 9
ジェフユナイテッド市原 48640 3
ベガルタ仙台 48430 15
東京ヴェルディ 46500 8
大分トリニータ 39680 14
FC東京 39080 4
ヴィッセル神戸 38500 13
京都パープルサンガ 35030 16

plot of chunk main

2004年のデータ


<!– html table generated in R 2.15.1 by xtable 1.7-0 package –>

salary ranking
横浜F・マリノス 97740 2
ジュビロ磐田 83600 5
鹿島アントラーズ 81980 6
浦和レッドダイヤモンズ 77140 1
柏レイソル 67320 16
ガンバ大阪 65620 3
名古屋グランパスエイト 65070 7
清水エスパルス 62190 14
ヴィッセル神戸 53700 11
東京ヴェルディ 51500 9
サンフレッチェ広島 46930 12
セレッソ大阪 44950 15
FC東京 44920 8
ジェフユナイテッド市原 44000 4
アルビレックス新潟 36440 10
大分トリニータ 36170 13

plot of chunk main

2005年のデータ


<!– html table generated in R 2.15.1 by xtable 1.7-0 package –>

salary ranking
ジュビロ磐田 102040 6
鹿島アントラーズ 84460 3
横浜F・マリノス 76230 9
清水エスパルス 71830 15
ガンバ大阪 70860 1
ヴィッセル神戸 69160 18
浦和レッドダイヤモンズ 67800 2
柏レイソル 63000 16
大宮アルディージャ 62790 13
東京ヴェルディ 57380 17
名古屋グランパスエイト 55470 14
FC東京 52490 10
アルビレックス新潟 51730 12
セレッソ大阪 51070 5
ジェフユナイテッド市原 48360 4
サンフレッチェ広島 47800 7
大分トリニータ 42040 11
川崎フロンターレ 41640 8

plot of chunk main

2006年のデータ


<!– html table generated in R 2.15.1 by xtable 1.7-0 package –>

salary ranking
浦和レッドダイヤモンズ 120260 1
横浜F・マリノス 97600 9
ジュビロ磐田 89510 5
ガンバ大阪 87240 3
鹿島アントラーズ 87080 6
名古屋グランパスエイト 74160 7
大宮アルディージャ 62800 12
サンフレッチェ広島 62070 10
FC東京 60140 13
清水エスパルス 58840 4
ジェフユナイテッド市原 56510 11
セレッソ大阪 51050 17
アルビレックス新潟 47940 14
大分トリニータ 44450 8
京都パープルサンガ 42150 18
アビスパ福岡 40770 16
川崎フロンターレ 40060 2
ヴァンフォーレ甲府 29700 15

plot of chunk main

2007年のデータ


<!– html table generated in R 2.15.1 by xtable 1.7-0 package –>

salary ranking
浦和レッドダイヤモンズ 128110 2
横浜F・マリノス 84320 7
ガンバ大阪 83690 3
名古屋グランパスエイト 76510 11
ジュビロ磐田 63580 9
鹿島アントラーズ 60380 1
清水エスパルス 58520 4
FC東京 58190 12
サンフレッチェ広島 55130 16
ヴィッセル神戸 52980 10
大宮アルディージャ 52740 15
柏レイソル 52580 8
川崎フロンターレ 52260 5
ジェフユナイテッド市原 48000 13
アルビレックス新潟 43240 6
大分トリニータ 40810 14
横浜FC 33240 18
ヴァンフォーレ甲府 25600 17

plot of chunk main

2008年のデータ


<!– html table generated in R 2.15.1 by xtable 1.7-0 package –>

salary ranking
浦和レッドダイヤモンズ 140760 7
鹿島アントラーズ 85410 1
ガンバ大阪 74780 8
清水エスパルス 67460 5
ジュビロ磐田 65518 16
名古屋グランパス 65010 3
横浜F・マリノス 64340 9
京都サンガF.C. 58740 14
ヴィッセル神戸 57270 10
東京ヴェルディ 54600 17
大宮アルディージャ 50670 12
川崎フロンターレ 50380 2
FC東京 46480 6
ジェフユナイテッド市原 45440 15
柏レイソル 41980 11
大分トリニータ 37950 4
アルビレックス新潟 37400 13
コンサドーレ札幌 31320 18

plot of chunk main

2009年のデータ


<!– html table generated in R 2.15.1 by xtable 1.7-0 package –>

salary ranking
浦和レッドダイヤモンズ 128310 6
鹿島アントラーズ 93110 1
ガンバ大阪 86360 3
京都サンガF.C. 73660 12
ヴィッセル神戸 71190 14
名古屋グランパス 69940 9
ジュビロ磐田 69890 11
川崎フロンターレ 67240 2
清水エスパルス 64040 7
サンフレッチェ広島 57490 4
横浜F・マリノス 55360 10
柏レイソル 54990 16
大宮アルディージャ 54230 13
大分トリニータ 52520 17
FC東京 51350 5
ジェフユナイテッド市原・千葉 48320 18
アルビレックス新潟 41030 8
モンテディオ山形 28840 15

plot of chunk main

2010年のデータ


<!– html table generated in R 2.15.1 by xtable 1.7-0 package –>

salary ranking
浦和レッドダイヤモンズ 107120 10
鹿島アントラーズ 95980 4
名古屋グランパス 93390 1
ガンバ大阪 86710 2
横浜F・マリノス 78700 8
清水エスパルス 76520 6
川崎フロンターレ 76270 5
ヴィッセル神戸 65600 15
サンフレッチェ広島 64070 7
ジュビロ磐田 59320 11
大宮アルディージャ 56680 12
京都サンガF.C. 51920 17
セレッソ大阪 49080 3
FC東京 45850 16
アルビレックス新潟 38920 9
ベガルタ仙台 32920 14
モンテディオ山形 32570 13
湘南ベルマーレ 29420 18

plot of chunk main

2011年のデータ


<!– html table generated in R 2.15.1 by xtable 1.7-0 package –>

salary ranking
名古屋グランパス 105790 2
浦和レッドダイヤモンズ 102680 15
ガンバ大阪 95820 3
鹿島アントラーズ 90930 6
柏レイソル 82450 1
横浜F・マリノス 76740 5
ヴィッセル神戸 70960 9
川崎フロンターレ 62580 11
サンフレッチェ広島 62150 7
大宮アルディージャ 62070 13
ジュビロ磐田 55640 8
清水エスパルス 53960 10
ベガルタ仙台 48790 4
セレッソ大阪 43380 12
モンテディオ山形 34270 18
アルビレックス新潟 33880 14
ヴァンフォーレ甲府 24170 16
アビスパ福岡 22840 17

plot of chunk main

## Error: replacement has length zero