dplyr 패키지를 조건부 돌연변이에 사용할 수 있습니까?
돌연변이가 조건부일 때(특정 열 값에 따라) 돌연변이를 사용할 수 있습니까?
이 예는 제가 의미하는 바를 보여주는 데 도움이 됩니다.
structure(list(a = c(1, 3, 4, 6, 3, 2, 5, 1), b = c(1, 3, 4,
2, 6, 7, 2, 6), c = c(6, 3, 6, 5, 3, 6, 5, 3), d = c(6, 2, 4,
5, 3, 7, 2, 6), e = c(1, 2, 4, 5, 6, 7, 6, 3), f = c(2, 3, 4,
2, 2, 7, 5, 2)), .Names = c("a", "b", "c", "d", "e", "f"), row.names = c(NA,
8L), class = "data.frame")
a b c d e f
1 1 1 6 6 1 2
2 3 3 3 2 2 3
3 4 4 6 4 4 4
4 6 2 5 5 5 2
5 3 6 3 3 6 2
6 2 7 6 7 7 7
7 5 2 5 2 6 5
8 1 6 3 6 3 2
저는 dplyr 패키지를 사용하여 제 문제에 대한 해결책을 찾고 싶었습니다(그리고 네, 이 코드가 작동해서는 안 되는 코드라는 것을 알고 있지만, 목적은 분명합니다). g:
library(dplyr)
df <- mutate(df,
if (a == 2 | a == 5 | a == 7 | (a == 1 & b == 4)){g = 2},
if (a == 0 | a == 1 | a == 4 | a == 3 | c == 4) {g = 3})
내가 찾고 있는 코드의 결과는 다음과 같은 특정 예제에서 다음과 같은 결과를 얻을 것입니다.
a b c d e f g
1 1 1 6 6 1 2 3
2 3 3 3 2 2 3 3
3 4 4 6 4 4 4 3
4 6 2 5 5 5 2 NA
5 3 6 3 3 6 2 NA
6 2 7 6 7 7 7 2
7 5 2 5 2 6 5 2
8 1 6 3 6 3 2 3
이 공급기를 어떻게 하는지 아는 사람 있나요?이 데이터 프레임은 하나의 예에 불과합니다. 제가 다루고 있는 데이터 프레임은 훨씬 더 큽니다.속도 때문에 dplyr을 사용하려고 했지만, 이 문제를 처리하는 다른 더 나은 방법이 있을까요?
사용하다ifelse
df %>%
mutate(g = ifelse(a == 2 | a == 5 | a == 7 | (a == 1 & b == 4), 2,
ifelse(a == 0 | a == 1 | a == 4 | a == 3 | c == 4, 3, NA)))
추가됨 - if_else: dplyr 0.5에는 다음이 있습니다.if_else
대체할 수 있도록 정의된 기능ifelse
와 함께if_else
하지만, 그 이후로if_else
보다 엄격함ifelse
(조건의 두 다리는 동일한 유형이어야 함) 그래서.NA
그 경우에는 로 대체되어야 할 것입니다.NA_real_
.
df %>%
mutate(g = if_else(a == 2 | a == 5 | a == 7 | (a == 1 & b == 4), 2,
if_else(a == 0 | a == 1 | a == 4 | a == 3 | c == 4, 3, NA_real_)))
추가됨 - case_이 질문이 게시된 이후 dplyr이 추가되었습니다.case_when
그래서 또 다른 대안은 다음과 같습니다.
df %>% mutate(g = case_when(a == 2 | a == 5 | a == 7 | (a == 1 & b == 4) ~ 2,
a == 0 | a == 1 | a == 4 | a == 3 | c == 4 ~ 3,
TRUE ~ NA_real_))
추가됨 - 산술/na_만약 값이 숫자이고 (마지막에 NA의 기본값을 제외한) 조건이 서로 배타적이라면, 우리는 다음을 사용하여 각 항에 원하는 결과를 곱하는 산술식을 사용할 수 있습니다.na_if
마지막에 0을 NA로 대체합니다.
df %>%
mutate(g = 2 * (a == 2 | a == 5 | a == 7 | (a == 1 & b == 4)) +
3 * (a == 0 | a == 1 | a == 4 | a == 3 | c == 4),
g = na_if(g, 0))
문제를 더 잘 처리할 수 있는 다른 방법을 묻기 때문에 다음과 같은 방법이 있습니다.data.table
:
require(data.table)
setDT(df)
df[a %in% c(0,1,3,4) | c == 4, g := 3L]
df[a %in% c(2,5,7) | (a==1 & b==4), g := 2L]
조건문의 순서는 반대로 다음과 같습니다.g
정확하게의 사본은 없습니다.g
두 번째 과제 중에도 만들어짐 - 제자리에서 대체됨.
더 큰 데이터에서는 중첩된 데이터를 사용하는 것보다 성능이 더 우수합니다. if-else
'예' 및 '아니오' 사례를 모두 평가할 수 있으며, 중첩은 IMHO를 읽기/유지하기 어려워질 수 있습니다.
다음은 비교적 큰 데이터에 대한 벤치마크입니다.
# NB: benchmark timings are as of R 3.1.0, data.table v1.9.2
require(data.table)
require(dplyr)
DT <- setDT(lapply(1:6, function(x) sample(7, 1e7, TRUE)))
setnames(DT, letters[1:6])
# > dim(DT)
# [1] 10000000 6
DF <- as.data.frame(DT)
DT_fun <- function(DT) {
DT[(a %in% c(0,1,3,4) | c == 4), g := 3L]
DT[a %in% c(2,5,7) | (a==1 & b==4), g := 2L]
}
DPLYR_fun <- function(DF) {
mutate(DF, g = ifelse(a %in% c(2,5,7) | (a==1 & b==4), 2L,
ifelse(a %in% c(0,1,3,4) | c==4, 3L, NA_integer_)))
}
BASE_fun <- function(DF) { # R v3.1.0
transform(DF, g = ifelse(a %in% c(2,5,7) | (a==1 & b==4), 2L,
ifelse(a %in% c(0,1,3,4) | c==4, 3L, NA_integer_)))
}
system.time(ans1 <- DT_fun(DT))
# user system elapsed
# 2.659 0.420 3.107
system.time(ans2 <- DPLYR_fun(DF))
# user system elapsed
# 11.822 1.075 12.976
system.time(ans3 <- BASE_fun(DF))
# user system elapsed
# 11.676 1.530 13.319
identical(as.data.frame(ans1), as.data.frame(ans2))
# [1] TRUE
identical(as.data.frame(ans1), as.data.frame(ans3))
# [1] TRUE
이것이 당신이 요청한 대안인지 확실하지 않지만, 도움이 되길 바랍니다.
dplyr은 이제 기능이 있습니다.case_when
벡터화된 if를 제공합니다.구문이 에 비해 조금 이상합니다.mosaic:::derivedFactor
수 , 는 dplyr 방변로수에세액 NA 표스할만하지야, 다 상당히 .mosaic:::derivedFactor
.
df %>%
mutate(g = case_when(a %in% c(2,5,7) | (a==1 & b==4) ~ 2L,
a %in% c(0,1,3,4) | c == 4 ~ 3L,
TRUE~as.integer(NA)))
편집: 사용 중인 경우dplyr::case_when()
' 변수 0.7.0 패 버 를 변 이 ' 키 붙 야 여 ' 니 합 다 이 앞 '를 붙여야 ..$
write (예: 쓰기).$a == 1
東京의 case_when
).
벤치마크:벤치마크(Arun 게시물의 함수 재사용) 및 표본 크기 감소:
require(data.table)
require(mosaic)
require(dplyr)
require(microbenchmark)
set.seed(42) # To recreate the dataframe
DT <- setDT(lapply(1:6, function(x) sample(7, 10000, TRUE)))
setnames(DT, letters[1:6])
DF <- as.data.frame(DT)
DPLYR_case_when <- function(DF) {
DF %>%
mutate(g = case_when(a %in% c(2,5,7) | (a==1 & b==4) ~ 2L,
a %in% c(0,1,3,4) | c==4 ~ 3L,
TRUE~as.integer(NA)))
}
DT_fun <- function(DT) {
DT[(a %in% c(0,1,3,4) | c == 4), g := 3L]
DT[a %in% c(2,5,7) | (a==1 & b==4), g := 2L]
}
DPLYR_fun <- function(DF) {
mutate(DF, g = ifelse(a %in% c(2,5,7) | (a==1 & b==4), 2L,
ifelse(a %in% c(0,1,3,4) | c==4, 3L, NA_integer_)))
}
mosa_fun <- function(DF) {
mutate(DF, g = derivedFactor(
"2" = (a == 2 | a == 5 | a == 7 | (a == 1 & b == 4)),
"3" = (a == 0 | a == 1 | a == 4 | a == 3 | c == 4),
.method = "first",
.default = NA
))
}
perf_results <- microbenchmark(
dt_fun <- DT_fun(copy(DT)),
dplyr_ifelse <- DPLYR_fun(copy(DF)),
dplyr_case_when <- DPLYR_case_when(copy(DF)),
mosa <- mosa_fun(copy(DF)),
times = 100L
)
이것은 다음을 제공합니다.
print(perf_results)
Unit: milliseconds
expr min lq mean median uq max neval
dt_fun 1.391402 1.560751 1.658337 1.651201 1.716851 2.383801 100
dplyr_ifelse 1.172601 1.230351 1.331538 1.294851 1.390351 1.995701 100
dplyr_case_when 1.648201 1.768002 1.860968 1.844101 1.958801 2.207001 100
mosa 255.591301 281.158350 291.391586 286.549802 292.101601 545.880702 100
그derivedFactor
에서 합니다.mosaic
패키지는 이것을 처리하도록 설계된 것 같습니다.예를
library(dplyr)
library(mosaic)
df <- mutate(df, g = derivedFactor(
"2" = (a == 2 | a == 5 | a == 7 | (a == 1 & b == 4)),
"3" = (a == 0 | a == 1 | a == 4 | a == 3 | c == 4),
.method = "first",
.default = NA
))
에는 랩핑(결과요대인숫신표수랩있면다핑습니할려하시를자로)할 수 derivedFactor
순식간에as.numeric
derivedFactor
임의의 수의 조건에도 사용할 수 있습니다.
case_when
이제 다음과 같은 경우 SQL 스타일 사례를 상당히 완벽하게 구현했습니다.
structure(list(a = c(1, 3, 4, 6, 3, 2, 5, 1), b = c(1, 3, 4,
2, 6, 7, 2, 6), c = c(6, 3, 6, 5, 3, 6, 5, 3), d = c(6, 2, 4,
5, 3, 7, 2, 6), e = c(1, 2, 4, 5, 6, 7, 6, 3), f = c(2, 3, 4,
2, 2, 7, 5, 2)), .Names = c("a", "b", "c", "d", "e", "f"), row.names = c(NA,
8L), class = "data.frame") -> df
df %>%
mutate( g = case_when(
a == 2 | a == 5 | a == 7 | (a == 1 & b == 4 ) ~ 2,
a == 0 | a == 1 | a == 4 | a == 3 | c == 4 ~ 3
))
dplyr 0.7.4 사용
설명서: http://dplyr.tidyverse.org/reference/case_when.html
언급URL : https://stackoverflow.com/questions/24459752/can-dplyr-package-be-used-for-conditional-mutating
'programing' 카테고리의 다른 글
iphone: 충돌 보고서에서 .dSYM 파일이 있는 위치 (0) | 2023.07.06 |
---|---|
Microsoft SQL Server의 특정 순서 위치에 새 테이블 열 추가 (0) | 2023.07.06 |
WordPress다른 언어로 클릭할 때 로고 이미지 변경 (0) | 2023.07.06 |
SSIS - 잠재적인 데이터 손실로 인해 값을 변환할 수 없습니다. (0) | 2023.07.06 |
Spark, Python 및 MongoDB가 함께 작동하도록 하기 (0) | 2023.07.06 |