Получение ошибки "условие имеет длину> 1 и будет использоваться только первый элемент" при использовании цикла if else - PullRequest
1 голос
/ 27 октября 2019

Я новичок в R, пытаюсь создать новый столбец, который берет данные о времени из существующего столбца (формат 12 часов) и упрощает его. Например, измените «12:45» на «12», «4:00» на 4 и т. Д.

Вот что у меня есть:

df <- df %>%
mutate(NewTimeColumn = if (str_detect(OldTimeColumn, "^12") == TRUE)  {
"12"
} else if (str_detect(OldTimeColumn, "^1") == TRUE) {
"1"
} else if (str_detect(OldTimeColumn, "^2") == TRUE) {
"2"
} else if (str_detect(OldTimeColumn, "^3") == TRUE) {
"3" 

## and so on

} else {
"11"
})

Вот сообщения об ошибкахЯ получаю:

Warning messages:
1: In if (str_detect(tilt, "^12") == TRUE) { :
  the condition has length > 1 and only the first element will be used
2: In if (str_detect(tilt, "^1") == TRUE) { :
  the condition has length > 1 and only the first element will be used

Все значения в новом столбце заканчиваются на "1"

Ответы [ 2 ]

2 голосов
/ 27 октября 2019

Скорее всего, я буду использовать lubridate для правильной обработки вашего Time столбца. Вот пример макета.

#Data
df <- data.frame(Time = c("12:45", "6:00", "7:00", "8:11"))
# df
#   Time
# 1 12:45
# 2  6:00
# 3  7:00
# 4  8:11
# -------------------------------------------------------------------------
library(lubridate)

#Convert Time column to proper time format 
df$Time <- hm(df$Time)
# now df looks like 
# df
#   Time
# 1 12H 45M 0S
# 2   6H 0M 0S
# 3   7H 0M 0S
# 4  8H 11M 0S
# -------------------------------------------------------------------------
# Then create a column called Hour extracting the hour from Time
df$Hour <- hour(df$Time)
# -------------------------------------------------------------------------
# df
#         Time Hour
# 1 12H 45M 0S   12
# 2   6H 0M 0S    6
# 3   7H 0M 0S    7
# 4  8H 11M 0S    8

Надежда, которая помогает и экономит кучу вложенных ifelse при правильном обращении с пакетом, предназначенным для этого.

1 голос
/ 27 октября 2019

if и else должны использоваться при логических условиях длины 1. Вы спрашиваете, равен ли вектор (OldTimeColumn) некоторой длины n вектору одного значения TRUE- вот почему предупреждающее сообщение говорит о том, что оно говорит, и оно оценивает только первый элемент OldTimeColumn, сравнивая его с TRUE.

Лучшим способом для вашего конкретного примера может быть использованиеcase_when структура.

library(dplyr)
library(stringr)
df <- data.frame(
  OldTimeColumn = c("12", "1", "2", "3", "4"),
  stringsAsFactors = F
)
df <- df %>%
  mutate(NewTimeColumn = case_when(
    str_detect(OldTimeColumn, "^12") ~ "12",
    str_detect(OldTimeColumn, "^1") ~ "1",
    str_detect(OldTimeColumn, "^2") ~ "2",
    str_detect(OldTimeColumn, "^3") ~ "3",
    TRUE ~ "11"
  ))

df

  OldTimeColumn NewTimeColumn
1            12            12
2             1             1
3             2             2
4             3             3
5             4            11

Попытка сделать это с ifelse (которая работает с оценкой векторов) будет более громоздкой, но может быть выполнена:

df <- df %>%
  mutate(NewTimeColumn = ifelse(str_detect(OldTimeColumn, "^12") == TRUE,
         "12", ifelse(str_detect(OldTimeColumn, "^1") == TRUE, 
         "1", ifelse(str_detect(OldTimeColumn, "^2") == TRUE,
         "2", ifelse(str_detect(OldTimeColumn, "^3") == TRUE, "3", "11")))))
...