重塑错误 - 无效因子

Reshape error - invalid factor

提问人:Btibert3 提问时间:9/18/2010 最后编辑:Btibert3 更新时间:9/19/2010 访问量:2533

问:

我对 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 和周期为中心的新数据框,其余列汇总每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
r 数据操作

评论


答:

3赞 Gary Li 9/18/2010 #1

由于熔化后,所有度量变量将在同一列中,因此它们应为同一类型。在你的例子中,“团队”是性格,“目标”是数字,所以你得到了这个错误。

2赞 hadley 9/18/2010 #2

我认为您最好从软件包中使用它来解决此问题。你没有说你想如何汇总数据,但如果你想对每个变量使用不同的汇总函数,请查看函数,如果你想以同样的方式汇总所有变量,请查看函数。ddplyplyrsummarisecolwise

评论

0赞 Btibert3 9/18/2010
一如既往,感谢您的建议哈德利。我不太明白我要总结什么。我编辑了上面的帖子,以突出我希望新数据框的样子。我以前尝试过使用 sqldf 并且几乎得到了它,但认为您的某些软件包一定有一种更简单的方法。
0赞 Btibert3 9/19/2010 #3

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

## 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)
2赞 hadley 9/19/2010 #4

现在我明白你想做什么了,这是使用 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)

还有许多方法可以仅使用基本函数(例如,通过子集然后修改名称)