Mapply 语句返回不正确的值。怎么了?

Mapply statement is returning incorrect value. What is happening?

我正在尝试在我的数据框中创建一个新列。此列需要使用当前行中的 2 个值,并使用它们在另一个数据框中查找特定值——该特定值将插入到当前行的新列下。我 运行 遇到麻烦并在新列中得到不正确的值。

下面我会举例说明。

下面是我要添加一列的数据框。我正在尝试使用 Mapply 语句创建一个新列 (winner_adv),其中包含基于 winner_type.1 和 loser_type.1.

的优势乘数
First_pokemon         Second_pokemon    Winner                  Loser diff_hp diff_att diff_def diff_sp.att diff_sp.def diff_speed winner_type.1 winner_type.2 loser_type.1 loser_type.2
1      Larvitar                Nuzleaf   Nuzleaf               Larvitar      20        6      -10          15         -10         19         Grass          Dark         Rock       Ground
2      Virizion              Terrakion Terrakion               Virizion       0       39       18         -18         -39          0          Rock      Fighting        Grass     Fighting
3       Togetic               Beheeyem  Beheeyem                Togetic      20       35      -10          45         -10          0       Psychic                      Fairy       Flying
4        Slugma              Druddigon Druddigon                 Slugma      37       80       50         -10          50         28        Dragon                       Fire             
5       Omastar                Shuckle   Omastar                Shuckle      50       50     -105         105        -160         50          Rock         Water          Bug         Rock

所以,我运行声明如下。 “战斗”是我的原始数据框,如上所示。

battles$winner_adv <- mapply(findAdv, battles$winner_type.1, battles$loser_type.1)

findAdv <- function(t1, t2) {
  return(typechart[t1, t2])
}

它将我的“战斗”数据框转换成这个。

First_pokemon         Second_pokemon    Winner                  Loser diff_hp diff_att diff_def diff_sp.att diff_sp.def diff_speed winner_type.1 winner_type.2 loser_type.1 loser_type.2 winner_adv
1      Larvitar                Nuzleaf   Nuzleaf               Larvitar      20        6      -10          15         -10         19         Grass          Dark         Rock       Ground        1.0
2      Virizion              Terrakion Terrakion               Virizion       0       39       18         -18         -39          0          Rock      Fighting        Grass     Fighting        1.0
3       Togetic               Beheeyem  Beheeyem                Togetic      20       35      -10          45         -10          0       Psychic                      Fairy       Flying        1.0
4        Slugma              Druddigon Druddigon                 Slugma      37       80       50         -10          50         28        Dragon                       Fire                     1.0
5       Omastar                Shuckle   Omastar                Shuckle      50       50     -105         105        -160         50          Rock         Water          Bug         Rock        1.0
6        Joltik Aegislash Shield Forme    Joltik Aegislash Shield Forme     -10       -3     -100           7        -100          5           Bug      Electric        Steel        Ghost        0.5

但是,“winner_adv”列中的第一个值是错误的。它正在查看另一个数据框 (typechart) 以获取值。如下所示。

Normal Fire Water Electric Grass Ice Fighting Poison Ground Flying Psychic Bug Rock Ghost Dragon Dark Steel Fairy
Normal        1  1.0   1.0      1.0   1.0 1.0        1    1.0      1    1.0       1 1.0  0.5     0    1.0    1   0.5     1
Fire          1  0.5   0.5      1.0   2.0 2.0        1    1.0      1    1.0       1 2.0  0.5     1    0.5    1   2.0     1
Water         1  2.0   0.5      1.0   0.5 1.0        1    1.0      2    1.0       1 1.0  2.0     1    0.5    1   1.0     1
Electric      1  1.0   2.0      0.5   0.5 1.0        1    1.0      0    2.0       1 1.0  1.0     1    0.5    1   1.0     1
Grass         1  0.5   2.0      1.0   0.5 1.0        1    0.5      2    0.5       1 0.5  2.0     1    0.5    1   0.5     1
Ice           1  0.5   0.5      1.0   2.0 0.5        1    1.0      2    2.0       1 1.0  1.0     1    2.0    1   0.5     1

这意味着,在“battles”数据框的第一行——“winner_adv”值应该是:

typechart["Grass", "Rock"]
[1] 2

但它通过 Mapply 语句返回 1.0。我不确定为什么会这样。

这里是“battles”数据框的数据类型。后面是“typchart”的数据类型。

 $ First_pokemon : Factor w/ 800 levels "","Abomasnow",..: 350 753 712 649 507 314 488 380 536 776 ...
 $ Second_pokemon: Factor w/ 800 levels "","Abomasnow",..: 503 704 47 164 629 7 316 238 103 534 ...
 $ Winner        : Factor w/ 800 levels "","Abomasnow",..: 503 704 47 164 507 314 316 238 103 534 ...
 $ Loser         : Factor w/ 800 levels "","Abomasnow",..: 350 753 712 649 629 7 488 380 536 776 ...
 $ diff_hp       : int  20 0 20 37 50 -10 25 80 0 -5 ...
 $ diff_att      : int  6 39 35 80 50 -3 0 20 -12 25 ...
 $ diff_def      : int  -10 18 -10 50 -105 -100 -10 70 -28 10 ...
 $ diff_sp.att   : int  15 -18 45 -10 105 7 45 65 23 -5 ...
 $ diff_sp.def   : int  -10 -39 -10 50 -160 -100 50 85 28 20 ...
 $ diff_speed    : int  19 0 0 28 50 5 25 55 29 5 ...
 $ winner_type.1 : Factor w/ 18 levels "Bug","Dark","Dragon",..: 10 16 15 3 16 1 12 9 18 4 ...
 $ winner_type.2 : Factor w/ 19 levels "","Bug","Dark",..: 3 7 1 1 19 5 16 4 1 1 ...
 $ loser_type.1  : Factor w/ 18 levels "Bug","Dark","Dragon",..: 16 10 5 7 1 17 15 6 1 18 ...
 $ loser_type.2  : Factor w/ 19 levels "","Bug","Dark",..: 12 7 9 1 17 10 9 1 1 9 ...
 $ winner_adv    : num  1 1 1 1 1 0.5 1 1 1 1 ...
$ Normal  : num  1 1 1 1 1 1 2 1 1 1 ...
 $ Fire    : num  1 0.5 2 1 0.5 0.5 1 1 2 1 ...
 $ Water   : num  1 0.5 0.5 2 2 0.5 1 1 1 1 ...
 $ Electric: num  1 1 1 0.5 1 1 1 1 2 0.5 ...
 $ Grass   : num  1 2 0.5 0.5 0.5 2 1 2 0.5 2 ...
 $ Ice     : num  1 2 1 1 1 0.5 2 1 1 1 ...
 $ Fighting: num  1 1 1 1 1 1 1 1 1 2 ...
 $ Poison  : num  1 1 1 1 0.5 1 0.5 0.5 2 1 ...
 $ Ground  : num  1 1 2 0 2 2 1 0.5 1 1 ...
 $ Flying  : num  1 1 1 2 0.5 2 0.5 1 0 1 ...
 $ Psychic : num  1 1 1 1 1 1 0.5 1 1 1 ...
 $ Bug     : num  1 2 1 1 0.5 1 0.5 1 0.5 2 ...
 $ Rock    : num  0.5 0.5 2 1 2 1 2 0.5 2 0.5 ...
 $ Ghost   : num  0 1 1 1 1 1 0 0.5 1 1 ...
 $ Dragon  : num  1 0.5 0.5 0.5 0.5 2 1 1 1 1 ...
 $ Dark    : num  1 1 1 1 1 1 2 1 1 1 ...
 $ Steel   : num  0.5 2 1 1 0.5 0.5 2 0 2 0.5 ...
 $ Fairy   : num  1 1 1 1 1 1 0.5 2 1 1 ...

前面:

findAdv <- function(t1, t2) {
  return(typechart[as.character(t1), as.character(t2)])
}

factor这是你的问题。

findAdv <- function(t1, t2) {
  browser()
  return(typechart[t1, t2])
}

> mapply(findAdv, battles$winner_type.1, battles$loser_type.1)
Called from: (function(t1, t2) {
  browser()
  return(typechart[t1, t2])
  ...
Browse[1]> debug at #3: return(typechart[t1, t2])
Browse[2]> t1
[1] Grass
Levels: Dragon Grass Psychic Rock
Browse[2]> t2
[1] Rock
Levels: Bug Fairy Fire Grass Rock
Browse[2]> c(t1,t2)
[1] 2 5                                            # <--- here's a hint
Browse[2]> typechart[t1, t2]
[1] 2
Browse[2]> typechart[as.character(t1), as.character(t2)]
[1] 2

此时,意识到 typechart[2,5](不是 Grass/Rock)与 typechart["Grass","Rock"]value 相同,但它是typechart 矩阵中的位置不同。巧合。让我们按 continue 进入第二次迭代。

Browse[2]> c
Browse[2]> Called from: (function(t1, t2) {
  browser()
  return(typechart[t1, t2])
  ...
Browse[1]> debug at #3: return(typechart[t1, t2])
Browse[2]> c(t1,t2)
[1] 4 4
Browse[2]> typechart[t1, t2]
[1] 0.5
Browse[2]> typechart[as.character(t1), as.character(t2)]
Error in typechart[as.character(t1), as.character(t2)] (from #3) : 
  subscript out of bounds
    x
 1. \-base::mapply(findAdv, battles$winner_type.1, battles$loser_type.1)
 2.   \-(function (t1, t2) ...
Browse[2]> c(as.character(t1), as.character(t2))
[1] "Rock"  "Grass"

它会产生错误,因为您的示例数据不完整:虽然我们至少有 4 行和 4 列(当使用 factors 的整数格式时),但我们没有一行"Rock".

你的数据中,我希望这不会产生错误,而是会给你一个不同的查找值。


数据:

battles <- structure(list(First_pokemon = structure(c(1L, 5L, 4L, 3L, 2L), .Label = c("Larvitar", "Omastar", "Slugma", "Togetic", "Virizion"), class = "factor"), Second_pokemon = structure(c(3L, 5L, 1L, 2L, 4L), .Label = c("Beheeyem", "Druddigon", "Nuzleaf", "Shuckle", "Terrakion"), class = "factor"), Winner = structure(c(3L, 5L, 1L, 2L, 4L), .Label = c("Beheeyem", "Druddigon", "Nuzleaf", "Omastar", "Terrakion"), class = "factor"), Loser = structure(c(1L, 5L, 4L, 3L, 2L), .Label = c("Larvitar", "Shuckle", "Slugma", "Togetic", "Virizion"), class = "factor"), diff_hp = c(20L, 0L, 20L, 37L, 50L), diff_att = c(6L, 39L, 35L, 80L, 50L), diff_def = c(-10L, 18L, -10L, 50L, -105L), diff_sp.att = c(15L, -18L, 45L, -10L, 105L), diff_sp.def = c(-10L, -39L, -10L, 50L, -160L), diff_speed = c(19L, 0L, 0L, 28L, 50L), winner_type.1 = structure(c(2L, 4L, 3L, 1L, 4L), .Label = c("Dragon", "Grass", "Psychic", "Rock"), class = "factor"),     winner_type.2 = structure(c(2L, 3L, 1L, 1L, 4L), .Label = c(".",     "Dark", "Fighting", "Water"), class = "factor"), loser_type.1 = structure(c(5L,     4L, 2L, 3L, 1L), .Label = c("Bug", "Fairy", "Fire", "Grass",     "Rock"), class = "factor"), loser_type.2 = structure(c(4L,     2L, 3L, 1L, 5L), .Label = c(".", "Fighting", "Flying", "Ground",     "Rock"), class = "factor")), class = "data.frame", row.names = c("1", "2", "3", "4", "5"))
typechart <- structure(c(1, 1, 1, 1, 1, 1, 1, 0.5, 2, 1, 0.5, 0.5, 1, 0.5, 0.5, 2, 2, 0.5, 1, 1, 1, 0.5, 1, 1, 1, 2, 0.5, 0.5, 0.5, 2, 1, 2, 1, 1, 1, 0.5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.5, 1, 1, 1, 2, 0, 2, 2, 1, 1, 1, 2, 0.5, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 0.5, 1, 0.5, 0.5, 2, 1, 2, 1, 0, 1, 1, 1, 1, 1, 1, 0.5, 0.5, 0.5, 0.5, 2, 1, 1, 1, 1, 1, 1, 0.5, 2, 1, 1, 0.5, 0.5, 1, 1, 1, 1, 1, 1), .Dim = c(6L, 18L), .Dimnames = list(c("Normal", "Fire", "Water", "Electric", "Grass", "Ice"), c("Normal", "Fire", "Water", "Electric", "Grass", "Ice", "Fighting", "Poison", "Ground", "Flying", "Psychic", "Bug", "Rock", "Ghost", "Dragon", "Dark", "Steel", "Fairy")))