提问人:Btibert3 提问时间:9/18/2010 最后编辑:Btibert3 更新时间:9/19/2010 访问量:2533
重塑错误 - 无效因子
Reshape error - invalid factor
问:
我对 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
答:
3赞
Gary Li
9/18/2010
#1
由于熔化后,所有度量变量将在同一列中,因此它们应为同一类型。在你的例子中,“团队”是性格,“目标”是数字,所以你得到了这个错误。
2赞
hadley
9/18/2010
#2
我认为您最好从软件包中使用它来解决此问题。你没有说你想如何汇总数据,但如果你想对每个变量使用不同的汇总函数,请查看函数,如果你想以同样的方式汇总所有变量,请查看函数。ddply
plyr
summarise
colwise
评论
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)
还有许多方法可以仅使用基本函数(例如,通过子集然后修改名称)
评论