我正在处理一个数据框,并在列中提取了0 t0 23的小时数据。我根据小时添加了一列作为当天的类型。我已经执行下面的循环,但得到错误。有人可以帮我解决下面的语法错误以及如何纠正错误。
for(i in data$Requesthours) {
if(data$Requesthours>=0 & data$Requesthours<3) {
data$Partoftheday <- "Midnight"
} else if(data$Requesthours>=3 & data$Requesthours<6) {
data$Partoftheday <- "Early Morning"
} else if(data$Requesthours>=6 & data$Requesthours<12) {
data$Partoftheday <- "Morning"
} else if(data$Requesthours>=12 & data$Requesthours<16) {
data$Partoftheday <- "Afternoon"
} else if(data$Requesthours>=16 & data$Requesthours<20) {
data$Partoftheday <- "Evening"
} else if(data$Requesthours>=20 & data$Requesthours<=23) {
data$Partoftheday <- "Night"
}
}
答案 0 :(得分:2)
仍在等待你发布你的错误,但这里是一个R编码提示,它将减少到一个单行(并绕过你的错误)。它也会更快(它的矢量化,不像你的for-loop和if-else-ladder)。
data$Partoftheday <- as.character(
cut(data$Requesthours,
breaks=c(-1,3,6,12,16,20,24),
labels=c('Midnight', 'Early Morning', 'Morning', 'Afternoon', 'Evening', 'Night')
)
)
# see Notes on cut() at bottom to explain this
现在回到你的错误:你对如何迭代R中的列感到困惑。for(i in data$Requesthours)
试图迭代你的df,但是你把索引与数据值混淆了。你也试着让i
成为一个迭代器,但是你没有在循环内的任何地方引用值i
,你会回到data$Requesthours
,这是一个完整的列而不是单个值(循环内容如何知道您所指的是哪个值?它们没有。您可以使用丑陋的显式索引循环,如for (i in 1:nrow(data) ...
或for (i in seq_along(data) ...
,然后访问data[i,]$Requesthours
,但请不要。因为......
关于学习R的一个重要的惯用之处通常是当你编写for循环来遍历数据框或df列时,你应该停下来思考(或研究)是否存在< R中的em>矢量化函数可以实现您想要的功能。 cut, if, sum, mean, max, diff, stdev, ...
fns都是矢量化的,所有算术和逻辑运算符都是如此。 '矢量化'意味着您可以将整个(列)矢量作为输入提供给它们,它们会生成一个完整的(列)矢量作为输出,您可以直接将其分配给新列。非常简单,非常快,非常强大。一般来说,裤子脱掉了。请阅读R-intro.html, esp. Section 2 about vector assignment
如果你找不到或写一个向量化的fn,那么*apply
函数族apply, sapply, lapply, ...
也可以将你想要的任意函数应用于list / vector / dataframe / df列。
cut(data, breaks, labels, ...)
是一个函数,其中data
是您的输入向量(例如,您选择的列data$Requesthours
),breaks
是整数或数字的向量,{{1是一个命名输出的向量。标签的长度不仅仅是中断,因为5个中断将您的数据划分为6个范围。 labels
应用于as.character()
的输出cut()
,我们必须将最低cutoff_hour 0调到-1,否则hr == 0会错误地给出NA。 (有一个参数(hr>=0 & hr<3)
,但它不是你想要的,因为它也会导致hr == 3为'Midnight',hr == 6为'Early Morning'等。)答案 1 :(得分:0)
if(data$Requesthours>=0 & data$Requesthours<3)
(以及其他类似的ifs)毫无意义,因为data$Requesthours
是向量。您应该尝试以下任一方法:
解决方案1:
for(i in seq(length(data$Requesthours))) {
if(data$Requesthours[i]>=0 & data$Requesthours[i]<3)
data$Partoftheday[i] <- "Midnight"
....
}
这个解决方案像地狱一样缓慢而且非常难看,但它会起作用。
解决方案2:
data$Partoftheday[data$Requesthours>=0 & data$Requesthours<3] <- "Midnight"
...
解决方案3 = smci提出的内容