重塑错误 - 无效因素

时间:2010-09-18 02:43:27

标签: r data-manipulation

我对R有点新,我遇到了一些需要帮助的地方。我认为重塑包可以完成我需要做的事情。

以下是原始数据框的结构:

> str(bruins)
'data.frame':   10 obs. of  6 variables:
 $ gameid  : Factor w/ 1 level "20090049": 1 1 1 1 1 1 1 1 1 1
 $ team    : chr  "NYI" "BOS" "NYI" "BOS" ...
 $ home_ind: chr  "V" "H" "V" "H" ...
 $ period  : Factor w/ 5 levels "1","2","3","4",..: 1 1 2 2 3 3 4 4 5 5
 $ goals   : int  0 0 3 0 0 3 0 0 3 3
 $ shots   : int  16 7 9 7 8 12 5 4 38 30

以下是前几行:

> head(bruins)
      gameid team home_ind period goals shots
409 20090049  NYI        V      1     0    16
410 20090049  BOS        H      1     0     7
411 20090049  NYI        V      2     3     9
412 20090049  BOS        H      2     0     7
413 20090049  NYI        V      3     0     8
414 20090049  BOS        H      3     3    12

我希望创建一个以gameid和period为中心的新数据框,其余列总结每个home_ind行的数据(总共10列)。

当我运行以下代码时:

b.melt <- melt(bruins, id=c("gameid", "period"), na.rm=TRUE)

我收到以下错误:

Warning messages:
1: In `[<-.factor`(`*tmp*`, ri, value = c(0L, 0L, 3L, 0L, 0L, 3L, 0L,  :
  invalid factor level, NAs generated
2: In `[<-.factor`(`*tmp*`, ri, value = c(16L, 7L, 9L, 7L, 8L, 12L,  :
  invalid factor level, NAs generated

非常感谢任何帮助!

编辑:这是我希望重组数据看起来像

    gameid period vis_team vis_goals vis_shots home_team home_goals home_shots
1 20090049      1     NYI      0      16       BOS          0          7
2 20090049      2     NYI      3      9        BOS          0          7
3 20090049      3     NYI      0      8        BOS          3         12

4 个答案:

答案 0 :(得分:3)

因为在熔化之后,所有测量变量都在同一列中,它们应该是相同的类型。在你的情况下,“团队”是字符,“目标”是数字,所以你得到了这个错误。

答案 1 :(得分:2)

我认为您最好使用ddply包中的plyr来解决此问题。您没有说明如何汇总数据,但如果要为每个变量使用不同的汇总函数,请查看summarise函数,如果要汇总所有函数,请查看colwise函数变量的方式相同。

答案 2 :(得分:2)

现在我看到你正在尝试做什么,这是一种使用plyr summarise的方法:

home <- summarise(subset(per, home_ind == "V"), 
  gameid = gameid, period = period, 
  vis_team = team, vis_goals = goals, vis_shots = shots)

away <- summarise(subset(per, home_ind == "H"), 
  gameid = gameid, period = period, 
  home_team = team, home_goals = goals, home_shots = shots)

join(home, away)

还有很多方法可以使用基本功能(例如通过子集化然后修改名称)

答案 3 :(得分:0)

感谢您的帮助。我最终走了一条不同的路线,把问题分成了几块。我确信这是更快,更优雅的方式,但我到了我需要的地方,并希望分享代码,以防这对其他人有帮助。

## load libraries 
library(sqldf)

## assume that the dataset is loaded
## restructure the data and merge together
sql.1 <- "SELECT gameid, period, team `vis_team`, goals `vis_goals`, shots `vis_shots`"
sql.2 <- "FROM per WHERE home_ind='V' GROUP BY gameid, period "
sql.cmd <- paste(sql.1, sql.2, sep="")
vis <- sqldf(sql.cmd)

sql.1 <- "SELECT gameid, period, team `home_team`, goals `home_goals`, shots `home_shots`"
sql.2 <- "FROM per WHERE home_ind='H' GROUP BY gameid, period "
sql.cmd <- paste(sql.1, sql.2, sep="")
home <- sqldf(sql.cmd)

my.dataset <- merge(vis, home)