이 답변은 기존 답변과 동일한 요소를 많이 다루지 만,이 문제 (열 이름을 함수에 전달)는 좀 더 포괄적으로 다루는 답변이 있기를 원할 정도로 자주 발생합니다.
매우 간단한 데이터 프레임이 있다고 가정합니다.
dat <- data.frame(x = 1:4,
y = 5:8)
우리는 새로운 열을 생성하는 기능을 쓰고 싶은 z
컬럼의 합 x
과 y
.
여기서 매우 일반적인 걸림돌은 자연 스럽지만 잘못된 시도가 종종 다음과 같이 보인다는 것입니다.
foo <- function(df,col_name,col1,col2){
df$col_name <- df$col1 + df$col2
df
}
#Call foo() like this:
foo(dat,z,x,y)
여기서 문제 df$col1
는 표현식을 평가하지 않는다는 것 col1
입니다. 단순히 df
라는 열을 찾습니다 col1
. 이 동작은 ?Extract
"재귀 (목록 형) 개체"섹션에 설명되어 있습니다.
가장 간단하고 가장 자주 권장되는 솔루션은 단순히에서 $
로 전환 [[
하여 함수 인수를 문자열로 전달하는 것입니다.
new_column1 <- function(df,col_name,col1,col2){
#Create new column col_name as sum of col1 and col2
df[[col_name]] <- df[[col1]] + df[[col2]]
df
}
> new_column1(dat,"z","x","y")
x y z
1 1 5 6
2 2 6 8
3 3 7 10
4 4 8 12
이것은 가장 망치기 어려운 방법이기 때문에 종종 "모범 사례"로 간주됩니다. 열 이름을 문자열로 전달하는 것은 가능한 한 모호하지 않습니다.
다음 두 가지 옵션이 더 고급입니다. 많은 인기있는 패키지가 이러한 종류의 기술을 사용하지만이를 잘 사용 하려면 미묘한 복잡성과 예상치 못한 실패 지점을 도입 할 수 있으므로 더 많은주의와 기술이 필요합니다. Hadley의 Advanced R 책 의이 섹션은 이러한 문제 중 일부에 대한 훌륭한 참고 자료입니다.
당신이 경우 정말 모든 따옴표를 입력에서 사용자를 저장하려면, 하나의 옵션을 사용하여 문자열로 베어, 인용 부호로 둘러싸이지 않은 열 이름을 변환 할 수 있습니다 deparse(substitute())
:
new_column2 <- function(df,col_name,col1,col2){
col_name <- deparse(substitute(col_name))
col1 <- deparse(substitute(col1))
col2 <- deparse(substitute(col2))
df[[col_name]] <- df[[col1]] + df[[col2]]
df
}
> new_column2(dat,z,x,y)
x y z
1 1 5 6
2 2 6 8
3 3 7 10
4 4 8 12
솔직히 말하면 어리석은 일입니다.에서와 같은 일을하고 있기 때문입니다 new_column1
. 단지 이름을 문자열로 변환하기위한 추가 작업을 많이합니다.
마지막으로, 정말 멋지게 추가 할 두 열의 이름을 전달하는 것보다 더 유연하고 두 변수의 다른 조합을 허용하는 것으로 결정할 수 있습니다. 이 경우 eval()
두 개의 열을 포함하는 표현식 을 사용 하는 것이 좋습니다.
new_column3 <- function(df,col_name,expr){
col_name <- deparse(substitute(col_name))
df[[col_name]] <- eval(substitute(expr),df,parent.frame())
df
}
재미로 나는 여전히 deparse(substitute())
새 열의 이름을 사용하고 있습니다. 여기에서 다음이 모두 작동합니다.
> new_column3(dat,z,x+y)
x y z
1 1 5 6
2 2 6 8
3 3 7 10
4 4 8 12
> new_column3(dat,z,x-y)
x y z
1 1 5 -4
2 2 6 -4
3 3 7 -4
4 4 8 -4
> new_column3(dat,z,x*y)
x y z
1 1 5 5
2 2 6 12
3 3 7 21
4 4 8 32
따라서 짧은 대답은 기본적으로 data.frame 열 이름을 문자열로 전달하고 [[
단일 열을 선택 하는 데 사용 하는 것입니다. 만에 탐구하기 시작 eval
, substitute
당신이 정말 당신이 무슨 일을하는지 알고있는 경우 등.