2015-04-16 15 views
12

Tôi có một bộ dữ liệu với cấu trúc sau:Làm thế nào để chuyển tên cột động trong dplyr vào chức năng tùy chỉnh?

Classes ‘tbl_df’ and 'data.frame': 10 obs. of 7 variables: 
$ GdeName : chr "Aeugst am Albis" "Aeugst am Albis" "Aeugst am Albis" "Aeugst am Albis" ... 
$ Partei : chr "BDP" "CSP" "CVP" "EDU" ... 
$ Stand1971: num NA NA 4.91 NA 3.21 ... 
$ Stand1975: num NA NA 5.389 0.438 4.536 ... 
$ Stand1979: num NA NA 6.2774 0.0195 3.4355 ... 
$ Stand1983: num NA NA 4.66 1.41 3.76 ... 
$ Stand1987: num NA NA 3.48 1.65 5.75 ... 

Tôi muốn cung cấp một chức năng cho phép để tính toán chênh lệch giữa giá trị nào, và tôi muốn làm điều này bằng dplyr s mutate chức năng như sau: (giả định các thông số fromto được thông qua như các đối số)

from <- "Stand1971" 
to <- "Stand1987" 

data %>% 
    mutate(diff = from - to) 

Tất nhiên, điều này không làm việc, như dplyr sử dụng đánh giá không chuẩn. Và tôi biết bây giờ có một giải pháp thanh lịch cho vấn đề này bằng cách sử dụng mutate_ và tôi đã đọc this vignette, nhưng tôi vẫn không thể có được đầu của tôi xung quanh nó.

Việc cần làm?

Dưới đây là vài dòng đầu tiên của tập dữ liệu cho một ví dụ tái sản xuất

structure(list(GdeName = c("Aeugst am Albis", "Aeugst am Albis", 
"Aeugst am Albis", "Aeugst am Albis", "Aeugst am Albis", "Aeugst am Albis", 
"Aeugst am Albis", "Aeugst am Albis", "Aeugst am Albis", "Aeugst am Albis" 
), Partei = c("BDP", "CSP", "CVP", "EDU", "EVP", "FDP", "FGA", 
"FPS", "GLP", "GPS"), Stand1971 = c(NA, NA, 4.907306434, NA, 
3.2109535926, 18.272143463, NA, NA, NA, NA), Stand1975 = c(NA, 
NA, 5.389079711, 0.4382328556, 4.5363022622, 18.749259742, NA, 
NA, NA, NA), Stand1979 = c(NA, NA, 6.2773722628, 0.0194647202, 
3.4355231144, 25.294403893, NA, NA, NA, 2.7055961071), Stand1983 = c(NA, 
NA, 4.6609804428, 1.412940467, 3.7563539244, 26.277246489, 0.8529335746, 
NA, NA, 2.601878177), Stand1987 = c(NA, NA, 3.4767860929, 1.6535933856, 
5.7451770193, 22.146844746, NA, 3.7453183521, NA, 13.702211858 
)), .Names = c("GdeName", "Partei", "Stand1971", "Stand1975", 
"Stand1979", "Stand1983", "Stand1987"), class = c("tbl_df", "data.frame" 
), row.names = c(NA, -10L)) 
+0

Nó không trả lời câu hỏi của bạn, nhưng có thể tốt hơn với bộ dữ liệu gọn gàng mà bạn có thể sử dụng 'lead (x) - x' để tính toán sự khác biệt giữa các giá trị tiếp theo cho tất cả các năm cùng một lúc. – hadley

Trả lời

12

Sử dụng phiên bản mới nhất của dplyr (> = 0,7), bạn có thể sử dụng toán tử rlang!! (đập-bang).

library(tidyverse) 
from <- "Stand1971" 
to <- "Stand1987" 

data %>% 
    mutate(diff=(!!as.name(from))-(!!as.name(to))) 

Bạn chỉ cần chuyển đổi các chuỗi thành tên bằng as.name và sau đó chèn chúng vào biểu thức. Thật không may tôi dường như phải sử dụng một vài dấu ngoặc đơn hơn tôi muốn, nhưng các nhà điều hành !! dường như rơi vào một thứ tự kỳ lạ-of-hoạt động.

câu trả lời gốc, dplyr (0.3- < 0,7):

Từ họa tiết đó (vignette("nse","dplyr")), interp() chức năng sử dụng lazyeval của

library(lazyeval) 

from <- "Stand1971" 
to <- "Stand1987" 

data %>% 
    mutate_(diff=interp(~from - to, from=as.name(from), to=as.name(to))) 
+0

Tại sao cách tiếp cận này "sexy" (hoặc được ưa thích) hơn là sử dụng 'dán'? – wnstnsmth

+1

interp() giúp chụp các môi trường thích hợp cũng quan trọng hơn khi bạn có nhiều chức năng phạm vi phức tạp hoặc không phải cơ sở – MrFlick

+7

@wnstnsmth cũng như chụp môi trường, trình đánh giá interp sẽ luôn hoạt động bất kể tên của các biến. Sử dụng dán chỉ là đặt một quả bom lỗi thời gian vào mã của bạn. – hadley

1

Tại sao không chỉ đơn giản paste?

Các vấn đề liên quan