Połącz mutate z wartościami warunkowymi
W dużej ramce danych ("myfile") z czterema kolumnami muszę dodać piątą kolumnę z wartościami conditonalnie na podstawie pierwszych czterech kolumn. Ostatnio stałem się wielkim fanem dplyr, głównie ze względu na jego szybkość w dużych zestawach danych. Więc zastanawiałem się, czy mogę poradzić sobie z moim problemem za pomocą funkcji mutate.
Mój dataframe (właściwie jego krótsza wersja) wygląda trochę tak:
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
Wartości piątej kolumny (V5) opierają się na pewnych warunkowych Zasady:
if (V1==1 & V2!=4){
V5 <- 1
}
else if (V2==4 & V3!=1){
V5 <- 2
}
else {
V5 <- 0
}
Teraz chcę użyć funkcji mutate, aby używać tych reguł we wszystkich wierszach (więc nie muszę używać wolnej pętli). Coś takiego (i tak, Wiem, że to nie działa w ten sposób!):
myfile <- mutate(myfile, if (V1==1 & V2!=4){V5 = 1}
else if (V2==4 & V3!=1){V5 = 2}
else {V5 = 0})
To powinien być wynik:
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
Jak to zrobić w dplyr
?
3 answers
Spróbuj tego:
myfile %>% mutate(V5 = (V1 == 1 & V2 != 4) + 2 * (V2 == 4 & V3 != 1))
Dając:
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
Lub to:
myfile %>% mutate(V5 = ifelse(V1 == 1 & V2 != 4, 1, ifelse(V2 == 4 & V3 != 1, 2, 0)))
Dając:
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
Zaproponuj lepszą nazwę dla ramki danych. myfile sprawia, że wydaje się, że zawiera nazwę pliku.
Powyżej użyto tego wejścia:
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"))
Update 1 od momentu zamieszczenia dplyr zmienił %.%
na %>%
więc odpowiednio zmodyfikowaliśmy odpowiedź.
Update 2 dplyr ma teraz case_when
, które zapewnia inne rozwiązanie:
myfile %>%
mutate(V5 = case_when(V1 == 1 & V2 != 4 ~ 1,
V2 == 4 & V3 != 1 ~ 2,
TRUE ~ 0))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-29 04:07:21
Z dplyr 0.7.2
możesz użyć bardzo przydatnej funkcji 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)
Należy pamiętać, że NA
nie są traktowane specjalnie, ponieważ może to wprowadzać w błąd. Funkcja zwróci NA
tylko wtedy, gdy nie zostanie spełniony żaden warunek. Jeśli umieścisz linię z TRUE ~ ...
, tak jak w moim przykładzie, wartość zwracana nigdy nie będzie NA
.
Musisz wyraźnie powiedzieć case_when
, aby umieścić NA
gdzie należy, dodając wypowiedź w stylu is.na(x$V1) | is.na(x$V3) ~ NA_integer_
. Podpowiedź: funkcja dplyr::coalesce()
może być tutaj naprawdę przydatna czasami!
Ponadto, NA
sam zwykle nie zadziała, musisz umieścić specjalne NA
wartości : NA_integer_
, NA_character_
lub NA_real_
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-30 05:04:25
Wygląda na to, że derivedFactor
z pakietu mosaic
został do tego zaprojektowany. W tym przykładzie wyglądałoby to mniej więcej tak:
library(mosaic)
myfile <- mutate(myfile, V5 = derivedFactor(
"1" = (V1==1 & V2!=4),
"2" = (V2==4 & V3!=1),
.method = "first",
.default = 0
))
(jeśli chcesz, aby wynik był liczbowy zamiast współczynnika, owiń derivedFactor
znakiem as.numeric
.)
Zauważ, że opcja .default
w połączeniu z .method = "first"
ustawia warunek "else" -- takie podejście jest opisane w pliku pomocy dla derivedFactor
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-22 20:14:44