Объединить мутировать с условными значениями
в большом фрейме данных ("myfile") с четырьмя столбцами я должен добавить пятый столбец со значениями, условно основанными на первых четырех столбцах. В последнее время я стал большим поклонником dplyr, в основном из-за своей скорости в больших наборах данных. Поэтому мне было интересно, могу ли я справиться с моей проблемой, используя функцию mutate.
мой фрейм данных (на самом деле его более короткая версия) выглядит примерно так:
V1 V2 V3 V4
1 1 2 3 5
2 2 4 4 1
3 1 4 1 1
4 4 5 1 3
5 5 5 5 4
значения пятого столбца (V5) основаны на некотором условном правила:
if (V1==1 & V2!=4){
V5 <- 1
}
else if (V2==4 & V3!=1){
V5 <- 2
}
else {
V5 <- 0
}
теперь я хочу использовать функцию mutate, чтобы использовать эти правила для всех строк (поэтому мне не нужно использовать медленный цикл). Что-то вроде этого (и да, я знаю, что это не работает таким образом!):
myfile <- mutate(myfile, if (V1==1 & V2!=4){V5 = 1}
else if (V2==4 & V3!=1){V5 = 2}
else {V5 = 0})
это должно быть результатом:
V1 V2 V3 V4 V5
1 1 2 3 5 1
2 2 4 4 1 2
3 1 4 1 1 0
4 4 5 1 3 0
5 5 5 5 4 0
об этом dplyr
?
3 ответа:
попробуйте это:
myfile %>% mutate(V5 = (V1 == 1 & V2 != 4) + 2 * (V2 == 4 & V3 != 1))
даем:
V1 V2 V3 V4 V5 1 1 2 3 5 1 2 2 4 4 1 2 3 1 4 1 1 0 4 4 5 1 3 0 5 5 5 5 4 0
или такой:
myfile %>% mutate(V5 = ifelse(V1 == 1 & V2 != 4, 1, ifelse(V2 == 4 & V3 != 1, 2, 0)))
даем:
V1 V2 V3 V4 V5 1 1 2 3 5 1 2 2 4 4 1 2 3 1 4 1 1 0 4 4 5 1 3 0 5 5 5 5 4 0
предлагаю вам получить лучшее имя для фрейма данных. myfile создает впечатление, что он содержит имя файла.
выше используется этот вход:
myfile <- structure(list(V1 = c(1L, 2L, 1L, 4L, 5L), V2 = c(2L, 4L, 4L, 5L, 5L), V3 = c(3L, 4L, 1L, 1L, 5L), V4 = c(5L, 1L, 1L, 3L, 4L )), .Names = c("V1", "V2", "V3", "V4"), class = "data.frame", row.names = c("1", "2", "3", "4", "5"))
обновление 1 С момента первоначальной публикации dplyr изменился
%.%
до%>%
так изменили ответ соответственно.обновление 2 dplyr и
case_when
, который предлагает другое решение:myfile %>% mutate(V5 = case_when(V1 == 1 & V2 != 4 ~ 1, V2 == 4 & V3 != 1 ~ 2, TRUE ~ 0))
С
dplyr 0.7.2
, вы можете использовать очень полезнымcase_when
функция :x=read.table( text="V1 V2 V3 V4 1 1 2 3 5 2 2 4 4 1 3 1 4 1 1 4 4 5 1 3 5 5 5 5 4") x$V5 = case_when(x$V1==1 & x$V2!=4 ~ 1, x$V2==4 & x$V3!=1 ~ 2, TRUE ~ 0)
обратите внимание:
NA
специально не обрабатываются, так как это может ввести в заблуждение. Функция вернетNA
только тогда, когда условие выполнено. Если вы ставите строку сTRUE ~ ...
, как и в моем примере, возвращаемое значение никогда не будетNA
.вы должны выразительно сказать
case_when
поставитьNA
где он принадлежит, добавив оператор, какis.na(x$V1) | is.na(x$V3) ~ NA_integer_
. Подсказка:dplyr::coalesce()
функция может быть очень полезна здесь иногда!кроме того,
NA
в одиночку, как правило, не работает, вы должны поставить специальныйNA
значения :NA_integer_
,NA_character_
илиNA_real_
.
похоже
derivedFactor
Сmosaic
пакет был разработан для этого. В этом примере, это будет выглядеть примерно так:library(mosaic) myfile <- mutate(myfile, V5 = derivedFactor( "1" = (V1==1 & V2!=4), "2" = (V2==4 & V3!=1), .method = "first", .default = 0 ))
(если вы хотите, чтобы результат был числовым, а не фактором, оберните
derivedFactor
Сas.numeric
.)отметим, что в сочетании с
.method = "first"
устанавливает условие "else" -- этот подход описан в файле справки дляderivedFactor
.