R-如果其他操作对于1600万行来说耗时太长



我有一个1600万行的数据帧,我希望在现有列Month的基础上添加一列。如果月份是3、4或5,则列"季节"将是春季等。

for (i in 1:nrow(df)) {
if (df$Month[[i]] %in% c(3,4,5)) {
df$Season[[i]] <- "Spring"
} else if (df$Month[[i]] %in% c(6,7,8)) {
df$Season[[i]] <- "Summer"
} else if (df$Month[[i]] %in% c(9,10,11)) {
df$Season[[i]] <- "Autumn"
} else if (df$Month[[i]] %in% c(12,1,2)) {
df$Season[[i]] <- "Winter"
}
}

然而,它要花很长时间才能完成。我能做什么?

一种更简单、更快的方法是创建一个月份和季节的数据框架,然后将其连接到父数据框架。

像这样:

seasons<-data.frame(Month=1:12, Season=c("Winter", "Winter", rep("Spring", 3), rep("Summer", 3), rep("Autumn", 3), "Winter"))
answer <- dplyr::left_join(df, seasons)

这是假设两个数据帧都具有匹配的列名";月份";。

我预计for循环的性能将提高1000倍左右。

这更符合@Dave2e的线条,但带有碱基R:

Season=c("Winter", "Winter", rep("Spring", 3),
rep("Summer", 3), rep("Autumn", 3), "Winter")
df<-data.frame(month=sample(1:12,10,replace=T)) #Sample data
df$season<-Season[df$month]
df
#   month season
#1      8 Summer
#2      8 Summer
#3      5 Spring
#4      7 Summer
#5      2 Winter
#6      4 Spring
#7     12 Winter
#8      7 Summer
#9     11 Autumn
#10     1 Winter

这一方法明显快于for循环方法。

使用for循环(1000行(:

#user  system elapsed 
#0.02    0.00    0.02

使用矢量化方法(1000行(:

#user  system elapsed 
#   0       0       0

使用system.time计算。

考虑到只有1000行,这种差异可能看起来微不足道。然而,随着行数的增加(在OP的情况下,为1600万(,差异变得非常大

相关内容

最新更新