我有像这样的data.frame
home <- c("MANU","CHELSEA")
away <- c("SWANSEA", "LIVERPOO")
GH <- c(3,4)
GA <- c(2,1)
df <- data.frame(home, away, GH, GA)
我想在df中添加一个列,根据结果填充一个点列:
calc <- function(df) {
df$POINTS <- 0
for(i in 1:nrow(df))
if(df$GA[i] > df$GH[i]) {
df$POINTS[i] <- 0.11
}
else {
df$POINTS[i] <- 0.22
print("a")
}
}
这给了我这个
> df
home away GH GA POINTS
1 MANU SWANSEA 3 2 0.00
2 CHELSEA LIVERPOO 4 1 0.11
为什么第一个记录的点数不是0.11?
答案 0 :(得分:2)
我强烈建议使用data.table,而不是data.frame。数据表更易读,对基于规则的数据操作有更好的支持,如果数据集增长,数据表也会更快。
以下是解决问题的方法:
library(data.table)
home <- c("MANU","CHELSEA")
away <- c("SWANSEA", "LIVERPOO")
GH <- c(3,1)
GA <- c(2,3)
dt <- data.table(home, away, GH, GA)
dt[, POINTS:=ifelse(GH>GA, 0.22, 0.11) ]
第一行设置数据表:
home away GH GA
1: MANU SWANSEA 3 2
2: CHELSEA LIVERPOO 1 3
第二个添加到您的规则集中:
> dt
home away GH GA POINTS
1: MANU SWANSEA 3 2 0.22
2: CHELSEA LIVERPOO 1 3 0.11
我还纠正了切尔西赢得足球比赛的错误。这些天似乎不太可能。
干杯
评论后更新
啊哈。这基本上是个人喜好的问题。只要您可以建立一个清晰的规则集,就有很多方法可以对其进行编码。有些人喜欢紧凑的代码,我倾向于喜欢人类的可读性。
因此你可以这样做:
dt[GH>GA, comment := "home victory"]
dt[GH<GA, comment := "away victory"]
dt[GH==GA, comment := "draw"]
或者像这样:
dt[, home.points:=ifelse(GH>GA, 3, 0) + ifelse(GH==GA, 1, 0) + ifelse(GH<GA, 0, 0) ]
查看data.table的任何教程,你会很容易看出这种情况的灵活性。
答案 1 :(得分:1)
我们不需要这个循环
df$POINTS <- c(0.22, 0.11)[(df$GA>df$GH)+1L]
或者我们也可以使用ifelse
。
答案 2 :(得分:0)
如果你真的想使用函数和for
循环,你可以这样做:
calc<-function(df){
for(i in 1:nrow(df)){ # brackets after the for
if(df$GA[i] > df$GH[i]) { # no need to initialize POINTS
df$POINTS[i] <- 0.11} else {
df$POINTS[i] <- 0.22
print("a")
}
}
return(df) # so that the function "returns" something
}
然后您可以df<-calc(df)
df
,新列的值会很高。
但我建议您使用ifelse
:df$POINTS<-ifelse(df$GA>df$GH,0.11,0.22)
您当然可以合并多个ifelse
语句。第一个参数是测试,第二个参数是测试为TRUE时的值,如果测试为FALSE则为最后一个值。
多个ifelse
的示例:
ifelse(df$home=='MANU',0.3,ifelse(df$GA>df$GH,0.11,0.22))
# [1] 0.30 0.22 # as expected