'dplyr'의 새 열/변수에 동적 이름 사용
사용하고 싶습니다.dplyr::mutate()
데이터 프레임에 여러 개의 새 열을 만듭니다.열 이름과 해당 내용은 동적으로 생성되어야 합니다.
홍채의 데이터 예제:
library(dplyr)
iris <- as_tibble(iris)
나는 새로운 열을 변형시키는 함수를 만들었습니다.Petal.Width
변수:
multipetal <- function(df, n) {
varname <- paste("petal", n , sep=".")
df <- mutate(df, varname = Petal.Width * n) ## problem arises here
df
}
이제 열을 작성하기 위해 루프를 만듭니다.
for(i in 2:5) {
iris <- multipetal(df=iris, n=i)
}
그러나 mutate는 varname이 문자 변수 이름이라고 생각하기 때문에 루프는 4개(petal.2 - petal.5라고 함)가 아닌 하나의 새 변수(varname이라고 함)만 생성합니다.
어떻게 해야 합니까?mutate()
내 동적 이름을 변수 이름으로 사용하는 것?
변수 이름을 문자 값으로 동적으로 작성하기 때문에 열 이름에 문자 값을 허용하는 표준 data.frame 인덱싱을 사용하여 할당을 수행하는 것이 더 합리적입니다.예:
multipetal <- function(df, n) {
varname <- paste("petal", n , sep=".")
df[[varname]] <- with(df, Petal.Width * n)
df
}
그mutate
함수를 사용하면 명명된 매개 변수를 통해 새 열의 이름을 쉽게 지정할 수 있습니다.그러나 이는 명령을 입력할 때 이름을 알고 있다고 가정합니다.열 이름을 동적으로 지정하려면 명명된 인수도 작성해야 합니다.
dplyr 버전 >= 1.0
에서는 "dplyr 버서는사구있수다니습"의 구문을 할 수 .glue
시 매개변수 시 (package):=
에 그서여기에래여기.{}
이름에서 내부 식을 평가하여 값을 가져옵니다.
multipetal <- function(df, n) {
mutate(df, "petal.{n}" := Petal.Width * n)
}
열 이름을 사용할 수 있습니다.{{}}
뿐 아니라 에서도 사용할 수 .
meanofcol <- function(df, col) {
mutate(df, "Mean of {{col}}" := mean({{col}}))
}
meanofcol(iris, Petal.Width)
dplyr 버전 >= 0.7
dplyr
부터는 0.7 버전을 사용할 수 .:=
매개 변수 이름을 동적으로 할당합니다.다음과 같이 함수를 작성할 수 있습니다.
# --- dplyr version 0.7+---
multipetal <- function(df, n) {
varname <- paste("petal", n , sep=".")
mutate(df, !!varname := Petal.Width * n)
}
내용은 사용 하십시오.vignette("programming", "dplyr")
.
dplyr (>=0.3 & <0.7)
더 이전 버전의 버약간전전이.dplyr
(>=0.3 <0.7), 많은 기능에 대한 "표준 평가" 대안의 사용을 장려했습니다. evaluation (비표준 평가 vignett)을 참조하십시오.vignette("nse")
).
그래서 여기서 답은 다음과 같습니다.mutate_()
mutate()
수행:
# --- dplyr version 0.3-0.5---
multipetal <- function(df, n) {
varname <- paste("petal", n , sep=".")
varval <- lazyeval::interp(~Petal.Width * n, n=n)
mutate_(df, .dots= setNames(list(varval), varname))
}
dplyr < 0.3
의 이전버경가능도합다니우에전에서도 합니다.dplyr
질문이 처음 제기되었을 때 존재했던 것.신중한 사용이 필요합니다.quote
그리고.setName
:
# --- dplyr versions < 0.3 ---
multipetal <- function(df, n) {
varname <- paste("petal", n , sep=".")
pp <- c(quote(df), setNames(list(quote(Petal.Width * n)), varname))
do.call("mutate", pp)
}
의 새로운 에서.dplyr
(0.6.0
in 2017년 4월 4일), 과제(2017년 4월 4일)도 할 수 .:=
) 및는 따옴표를 열 !!
) 그것을 평가하지 않음
library(dplyr)
multipetalN <- function(df, n){
varname <- paste0("petal.", n)
df %>%
mutate(!!varname := Petal.Width * n)
}
data(iris)
iris1 <- tbl_df(iris)
iris2 <- tbl_df(iris)
for(i in 2:5) {
iris2 <- multipetalN(df=iris2, n=i)
}
@@MrFlik에 한 출력 multipetal
iris1''에
identical(iris1, iris2)
#[1] TRUE
많은 시행착오 끝에 패턴을 찾았습니다.!!rlang::sym("my variable"))
의 R: (R 전버서는에이전::UQ(rlang::sym("my variable")))
및 합니다.) 문자열 및 dplyr 동사 작업에 매우 유용합니다.그것은 많은 놀라운 상황에서 작동하는 것처럼 보입니다.
▁example다니예입▁here▁ans'에 대한 예를 들어보겠습니다.mutate
두 열을 함께 추가하는 함수를 만들고, 두 열 이름을 모두 문자열로 전달하려고 합니다.이 패턴을 연산자인 이패을연할함께수있다습니사용할과 함께 할 수 .:=
이를 위해.
## Take column `name1`, add it to column `name2`, and call the result `new_name`
mutate_values <- function(new_name, name1, name2){
mtcars %>%
mutate(!!rlang::sym(new_name) := !!rlang::sym(name1) + !!rlang::sym(name2))
}
mutate_values('test', 'mpg', 'cyl')
패턴은 다른 패턴과 함께 작동합니다.dplyr
기능도 제공합니다. »filter
:
## filter a column by a value
filter_values <- function(name, value){
mtcars %>%
filter(!!rlang::sym(name) != value)
}
filter_values('gear', 4)
또는arrange
:
## transform a variable and then sort by it
arrange_values <- function(name, transform){
mtcars %>%
arrange((!!rlang::sym(name)) %>% (!!rlang::sym(transform)))
}
arrange_values('mpg', 'sin')
위해서select
패턴을 사용할 필요가 없습니다.에 대사용수있다니습할신을 할 수 .!!
:
## select a column
select_name <- function(name){
mtcars %>%
select(!!name)
}
select_name('mpg')
우리는 곱슬곱슬한 연산자를 가지고 있습니다.{{}}
를 매우 수 있습니다 이것은 이것을 매우 쉽게 만듭니다.열, 동열이할당왼나쪽면타나에의이름적을 사용합니다.:=
.
library(dplyr)
library(rlang)
iris1 <- tbl_df(iris)
multipetal <- function(df, n) {
varname <- paste("petal", n , sep=".")
mutate(df, {{varname}} := Petal.Width * n)
}
multipetal(iris1, 4)
# A tibble: 150 x 6
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species petal.4
# <dbl> <dbl> <dbl> <dbl> <fct> <dbl>
# 1 5.1 3.5 1.4 0.2 setosa 0.8
# 2 4.9 3 1.4 0.2 setosa 0.8
# 3 4.7 3.2 1.3 0.2 setosa 0.8
# 4 4.6 3.1 1.5 0.2 setosa 0.8
# 5 5 3.6 1.4 0.2 setosa 0.8
# 6 5.4 3.9 1.7 0.4 setosa 1.6
# 7 4.6 3.4 1.4 0.3 setosa 1.2
# 8 5 3.4 1.5 0.2 setosa 0.8
# 9 4.4 2.9 1.4 0.2 setosa 0.8
#10 4.9 3.1 1.5 0.1 setosa 0.4
# … with 140 more rows
따옴표로 묶은/따옴표로 묶지 않은 변수 이름을 열 이름으로 전달할 수도 있습니다.
multipetal <- function(df, name, n) {
mutate(df, {{name}} := Petal.Width * n)
}
multipetal(iris1, temp, 3)
# A tibble: 150 x 6
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species temp
# <dbl> <dbl> <dbl> <dbl> <fct> <dbl>
# 1 5.1 3.5 1.4 0.2 setosa 0.6
# 2 4.9 3 1.4 0.2 setosa 0.6
# 3 4.7 3.2 1.3 0.2 setosa 0.6
# 4 4.6 3.1 1.5 0.2 setosa 0.6
# 5 5 3.6 1.4 0.2 setosa 0.6
# 6 5.4 3.9 1.7 0.4 setosa 1.2
# 7 4.6 3.4 1.4 0.3 setosa 0.900
# 8 5 3.4 1.5 0.2 setosa 0.6
# 9 4.4 2.9 1.4 0.2 setosa 0.6
#10 4.9 3.1 1.5 0.1 setosa 0.3
# … with 140 more rows
에서 동일하게 작동합니다.
multipetal(iris1, "temp", 3)
여기 다른 버전이 있는데, 거의 틀림없이 조금 더 단순합니다.
multipetal <- function(df, n) {
varname <- paste("petal", n, sep=".")
df<-mutate_(df, .dots=setNames(paste0("Petal.Width*",n), varname))
df
}
for(i in 2:5) {
iris <- multipetal(df=iris, n=i)
}
> head(iris)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species petal.2 petal.3 petal.4 petal.5
1 5.1 3.5 1.4 0.2 setosa 0.4 0.6 0.8 1
2 4.9 3.0 1.4 0.2 setosa 0.4 0.6 0.8 1
3 4.7 3.2 1.3 0.2 setosa 0.4 0.6 0.8 1
4 4.6 3.1 1.5 0.2 setosa 0.4 0.6 0.8 1
5 5.0 3.6 1.4 0.2 setosa 0.4 0.6 0.8 1
6 5.4 3.9 1.7 0.4 setosa 0.8 1.2 1.6 2
최신/캐주얼용으로 간소화된 깔끔한 평가 API와 문서를 제공하는 패키지를 즐길 수 있습니다.dplyr
user.sys입니다.
.mutate
열 이름으로 처리합니다.그래서 사용하기friendlyeval
당신은 다음과 같이 쓸 수 있습니다.
multipetal <- function(df, n) {
varname <- paste("petal", n , sep=".")
df <- mutate(df, !!treat_string_as_col(varname) := Petal.Width * n)
df
}
for(i in 2:5) {
iris <- multipetal(df=iris, n=i)
}
어느 쪽이 전화를 걸었습니까?rlang
하는 기능varname
열 이름으로 유효합니다.
friendlyeval
코드는 RStudio addin을 사용하여 언제든지 동등한 평이한 평가 코드로 변환할 수 있습니다.
제가 답변을 검색할 때 이 항목에 왔는데, 이것이 제가 필요로 하는 것과 거의 같았지만, @MrFlik의 답변과 Lazyeval vignetes를 통해 얻은 것이 조금 더 필요했기 때문에 저는 이것을 조금 더 보강하는 답변을 추가합니다.
문자열에서 Date 객체로 변환하고자 하는 데이터 프레임과 열 이름의 벡터(문자열)를 가져올 수 있는 함수를 만들고 싶었습니다. 만드는지 모르겠어요as.Date()
문자열인 인수를 가져와 열로 변환하여 아래와 같이 수행했습니다.
SE mutate를 통해 이 작업을 수행한 방법은 다음과 같습니다.mutate_()
및 ) 및그.dots
. 을 더 좋게 은 환영합니다이것을 더 좋게 만드는 비판은 환영합니다.
library(dplyr)
dat <- data.frame(a="leave alone",
dt="2015-08-03 00:00:00",
dt2="2015-01-20 00:00:00")
# This function takes a dataframe and list of column names
# that have strings that need to be
# converted to dates in the data frame
convertSelectDates <- function(df, dtnames=character(0)) {
for (col in dtnames) {
varval <- sprintf("as.Date(%s)", col)
df <- df %>% mutate_(.dots= setNames(list(varval), col))
}
return(df)
}
dat <- convertSelectDates(dat, c("dt", "dt2"))
dat %>% str
대화형 사용을 위해 dplyr을 사용하는 것을 즐기지만, lazyval::interp(), setNames 등의 해결 방법을 사용하려면 후프를 거쳐야 하기 때문에 dplyr을 사용하여 이 작업을 수행하는 것이 매우 까다롭습니다.
여기에 기본 R을 사용하는 더 간단한 버전이 있는데, 적어도 내가 보기에는 루프를 함수 안에 넣는 것이 더 직관적이고 @MrFlicks의 솔루션을 확장하는 것 같습니다.
multipetal <- function(df, n) {
for (i in 1:n){
varname <- paste("petal", i , sep=".")
df[[varname]] <- with(df, Petal.Width * i)
}
df
}
multipetal(iris, 3)
다른 다른대: 사용을 합니다.{}
동적 이름을 쉽게 만들 수 있는 내부 따옴표입니다.이것은 다른 솔루션과 비슷하지만 완전히 같지는 않으며, 저는 더 쉽다고 생각합니다.
library(dplyr)
library(tibble)
iris <- as_tibble(iris)
multipetal <- function(df, n) {
df <- mutate(df, "petal.{n}" := Petal.Width * n) ## problem arises here
df
}
for(i in 2:5) {
iris <- multipetal(df=iris, n=i)
}
iris
은 는이것이에서 온 것 같습니다.dplyr 1.0.0
하지만 확실하지 않습니다. (저도 가지고 있습니다.)rlang 4.7.0
중요한 경우)
동일한 작업이 여러 번 필요한 경우 일반적으로 데이터 형식이 최적이 아님을 나타냅니다. 원을는경우로 더 긴 .n
교차 결합을 통해 달성할 수 있는 data.frame의 열:
library(tidyverse)
iris %>% mutate(identifier = 1:n()) %>% #necessary to disambiguate row 102 from row 143 (complete duplicates)
full_join(tibble(n = 1:5), by=character()) %>% #cross join for long format
mutate(petal = Petal.Width * n) %>% #calculation in long format
pivot_wider(names_from=n, values_from=petal, names_prefix="petal.width.") #back to wider format (if desired)
결과:
# A tibble: 150 x 11
Sepal.Length Sepal.Width Petal.Length Petal.Width Species identifier petal.width.1 petal.width.2 petal.width.3
<dbl> <dbl> <dbl> <dbl> <fct> <int> <dbl> <dbl> <dbl>
1 5.1 3.5 1.4 0.2 setosa 1 0.2 0.4 0.6
2 4.9 3 1.4 0.2 setosa 2 0.2 0.4 0.6
3 4.7 3.2 1.3 0.2 setosa 3 0.2 0.4 0.6
4 4.6 3.1 1.5 0.2 setosa 4 0.2 0.4 0.6
5 5 3.6 1.4 0.2 setosa 5 0.2 0.4 0.6
6 5.4 3.9 1.7 0.4 setosa 6 0.4 0.8 1.2
7 4.6 3.4 1.4 0.3 setosa 7 0.3 0.6 0.9
8 5 3.4 1.5 0.2 setosa 8 0.2 0.4 0.6
9 4.4 2.9 1.4 0.2 setosa 9 0.2 0.4 0.6
10 4.9 3.1 1.5 0.1 setosa 10 0.1 0.2 0.3
# ... with 140 more rows, and 2 more variables: petal.width.4 <dbl>, petal.width.5 <dbl>
언급URL : https://stackoverflow.com/questions/26003574/use-dynamic-name-for-new-column-variable-in-dplyr
'programing' 카테고리의 다른 글
인터페이스에 클래스 바인딩 (0) | 2023.07.02 |
---|---|
조건을 기준으로 한 열 개수 (0) | 2023.07.02 |
스프링 부트 구성 요소는 단일 클래스를 포함할 수 있습니다. (0) | 2023.07.02 |
TypeScript에서 부울을 숫자로 캐스팅하는 방법(예: 0 또는 1) (0) | 2023.07.02 |
코드와 비교하여 전체 파일 git 비난을 표시하는 방법 (0) | 2023.07.02 |