如果这是一个初学者的问题,请原谅我。我对R.相对较新。我正在练习写作功能。我目前正在尝试编写一个函数,该函数采用代表时间的任何数值向量,并将每个观察分类为以下类别:"早晨","下午","晚上","晚上"。所有代表时间的向量都在军事时间。
time_cat <- function(df, column) {
select(df, column) %>%
mutate(time_category = ifelse(column %in% 500:1159, "Morning",
ifelse(column %in% 1200:1659, "Afternoon",
ifelse(column %in% 1700:2059, "Evening", "Night"))))
}
我使用nycflights13包中的航班数据集进行练习。但是,该功能似乎错误地将所有观察分类为&#34;夜晚&#34;类别。
time_cat(flights, "dep_time")
# A tibble: 336,776 x 2
dep_time time_category
<int> <chr>
1 517 Night
2 533 Night
3 542 Night
4 544 Night
5 554 Night
6 554 Night
7 555 Night
8 557 Night
9 557 Night
10 558 Night
# ... with 336,766 more rows
显然,所有这些观察结果应归类为&#34; Morning&#34;。
有人可以解释一下该代码有什么问题吗?
我将非常感激。
感谢。
答案 0 :(得分:1)
问题在于,在调用"dep_time"
时,它尝试将字符串mutate
与一系列数字匹配,而不是将数据框中该名称的列与数字范围。
例如,在下面的代码中,"a" == "b"
将第一次调用f
与"b" == "b"
和a
进行比较。在任何情况下都不使用列b
或dd <- data.frame(a = c("a", "b", "c"), b = c("A", "B", "C"))
f <- function(x) dd %>% mutate(new_column = x == "b")
f("a")
## a b new_column
## 1 a A FALSE
## 2 b B FALSE
## 3 c C FALSE
f("b")
## a b new_column
## 1 a A TRUE
## 2 b B TRUE
## 3 c C TRUE
。
time_cat <- function(df, column) {
column <- sym(column)
select(df, !!column) %>%
mutate(time_category = ifelse((!!column) %in% 500:1159, "Morning",
ifelse((!!column) %in% 1200:1659, "Afternoon",
ifelse((!!column) %in% 1700:2059, "Evening", "Night"))))
}
time_cat(flights, "dep_time")
要解决这个问题,请使用rlang软件包的tidyeval工具:
case_when
您也可能会发现使用time_cat <- function(df, column) {
column <- sym(column)
df %>%
select(!!column) %>%
mutate(time_category = case_when((!!column) %in% 500:1159 ~ "Morning",
(!!column) %in% 1200:1659 ~ "Afternoon",
(!!column) %in% 1700:2059 ~ "Evening",
TRUE ~ "Night"))
}
time_cat(flights, "dep_time")
更方便。此外,通常从管道左侧的输入开始。
{{1}}
答案 1 :(得分:0)
也许你们中的一些人会不同意我的观点,但是我不会使用某个函数,并且会使用data.table库来解决它:
library(data.table)
flights <- as.data.table(flights)
flights[dep_time < 1200, time_cat := "Morning"]
flights[dep_time > 1159 & dep_time < 1700, time_cat := "Afternoon"]
flights[dep_time > 1659 & dep_time < 2100, time_cat := "Evening"]
flights[dep_time > 2059, time_cat := "Night"]