2014-09-22 13 views
15

Đây là một câu hỏi khá đơn giản. Nhưng tôi không thể tìm thấy câu trả lời cho mỗi google/stackexchange và nhìn vào tài liệu của magrittr. Làm thế nào để bạn nạp kết quả của một chuỗi các hàm được kết nối thông qua%>% để tạo một vectơ?làm thế nào để nuôi sống là kết quả của một chuỗi ống (magrittr) đến một đối tượng

những gì tôi thấy hầu hết mọi người làm là:

a <- 
data.frame(x = c(1:3), y = (4:6)) %>% 
sum() 

nhưng là cũng có một giải pháp mà tôi có thể chỉ đường ống chuỗi kết quả để nuôi nó đến một đối tượng, có lẽ một bí danh hoặc sth của các loại tương tự phần nào như thế này:

data.frame(x = c(1:3), y = (4:6)) %>% 
sum() %>% 
a <-() 

điều này sẽ giúp giữ tất cả mã trong cùng một logic cho kết quả tìm kiếm về phía trước "xuống ống".

Trả lời

20

Hãy thử điều này:

data.frame(x = c(1:3), y = (4:6)) %>% sum -> a 
+7

+1 Tôi không bao giờ nghĩ rằng sẽ có một sự biện minh cho '->'. Bây giờ có! –

+5

Nhưng nếu bạn chỉ sử dụng '->' bạn không thể tiếp tục với chuỗi: ví dụ 'data.frame (x = c (1: 3), y = (4: 6))%>% sum -> a%>% exp' đưa ra một lỗi, bạn sẽ phải sử dụng dấu ngoặc đơn '(data.frame (x = c (1: 3), y = (4: 6))%>% sum -> a)%>% (exp) 'và nếu một trong những không cẩn thận có thể dẫn đến kết quả bất ngờ. –

+0

G. Grothendieck, tôi đã thử đoạn mã trên ('data.frame (x = c (1: 3), y = (4: 6))%>% (tổng -> a)%>% exp') , nhưng nó không chỉ định một cách chính xác kết quả một phần cho 'a'. –

11

Bạn có thể làm điều đó như vậy:

data.frame(x = c(1:3), y = (4:6)) %>% 
sum %>% 
assign(x="a",value=.,pos=1) 

Một vài điều cần lưu ý:

Bạn có thể sử dụng "" nói magrittr mà lập luận đối tượng được đưa về phía trước thuộc về. Theo mặc định nó là lần đầu tiên, nhưng ở đây tôi sử dụng . để cho biết rằng tôi muốn nó trong value số thứ hai để thay thế.

Thứ hai tôi đã phải sử dụng đối số pos=1 để làm nhiệm vụ trong môi trường toàn cầu.

+0

Bạn thực sự không nên sử dụng gán cho chỉ là về bất cứ điều gì. Đó là thực hành mã hóa xấu. – stanekam

+10

@iShouldUseAName Bạn có thể mở rộng trên đó không? Sự nguy hiểm ở đây là gì? –

3

Bạn cũng có thể sử dụng <<- điều hành:

data.frame(x = c(1:3), y = (4:6)) %>% 
    sum() %>% 
    `<<-`(a,.) 

Edit: Tôi nghĩ rằng John Paul là những gợi ý an toàn nhất, và bạn có thể tiếp tục đi với chuỗi làm bài tập khác nhau của kết quả từng phần. Ví dụ:

data.frame(x = c(1:3), y = (4:6)) %>% 
    sum %>% 
    assign(x="a",value=., pos=1) %>% 
    exp %>% 
    assign(x="b",value=., pos=1) %>% 
    sqrt %>% 
    assign(x="c", value=., pos=1) 

này sẽ tạo ra một cách chính xác a, bc.

+1

Bạn chắc chắn nó sẽ không hoạt động với '<-'? Tốt hơn không nên sử dụng '<< -' khi không được yêu cầu nghiêm ngặt. –

+1

@CarlWitthoft, nó sẽ không, toán tử '<-' sẽ gán cho môi trường cục bộ của hàm, do đó nó sẽ không tạo biến trong môi trường toàn cầu. –

2

Những gì tôi muốn làm (và tôi thấy thủ thuật này ở đâu đó tôi không thể nhớ) là sử dụng {.} -> obj ở phần cuối của chuỗi ống của tôi. Bằng cách này, tôi có thể thêm các bước bổ sung vào cuối chuỗi bằng cách chỉ chèn một dòng mới và không phải đặt lại vị trí cho toán tử gán ->.

Bạn cũng có thể sử dụng (.) isntead của {.} nhưng có vẻ hơi, lẻ.

Ví dụ, thay vì điều này:

iris %>% 
    ddply(.(Species), summarise, 
      mean.petal = mean(Petal.Length), 
      mean.sepal = mean(Sepal.Length)) -> summary 

Làm điều này:

iris %>% 
    ddply(.(Species), summarise, 
      mean.petal = mean(Petal.Length), 
      mean.sepal = mean(Sepal.Length)) %>% 
    {.} -> summary 

Nó làm cho nó dễ dàng hơn để xem nơi dữ liệu đường ống của bạn kết thúc. Ngoài ra, trong khi nó không có vẻ như một việc lớn, nó dễ dàng hơn để thêm một bước cuối cùng khi bạn không cần phải di chuyển -> xuống một dòng mới, chỉ cần thêm một dòng mới trước khi {.} và thêm bước.

Giống như vậy:

iris %>% 
    ddply(.(Species), summarise, 
      mean.petal = mean(Petal.Length), 
      mean.sepal = mean(Sepal.Length)) %>% 
    arrange(desc(mean.petal)) %>% # just add a step here 
    {.} -> summary 

này không giúp với tiết kiệm kết quả trung gian mặc dù. Câu trả lời của John Paul để sử dụng assign() là tốt, nhưng hơi dài để gõ. Bạn cần sử dụng . vì dữ liệu không phải là đối số đầu tiên, bạn phải đặt tên của đối số mới trong "" và chỉ định môi trường (pos = 1). Có vẻ như lười biếng đối với tôi, nhưng việc sử dụng %>% là khoảng tốc độ.

Vì vậy, tôi quấn assign() trong một chức năng nhỏ mà tốc độ nó lên một chút:

keep <- function(x, name) {assign(as.character(substitute(name)), x, pos = 1)} 

Vì vậy, bây giờ bạn có thể làm điều này:

keep <- function(x, name) {assign(as.character(substitute(name)), x, pos = 1)} 

    iris %>% 
    ddply(.(Species), summarise, 
      mean.petal = mean(Petal.Length), 
      mean.sepal = mean(Sepal.Length)) %>% keep(unsorted.data) %>% # keep this step 
    arrange(mean.petal) %>% 
    {.} -> sorted.data 

sorted.data 
#  Species mean.petal mean.sepal 
#1  setosa  1.462  5.006 
#2 versicolor  4.260  5.936 
#3 virginica  5.552  6.588 

unsorted.data 
#  Species mean.petal mean.sepal 
#1  setosa  1.462  5.006 
#2 versicolor  4.260  5.936 
#3 virginica  5.552  6.588 
Các vấn đề liên quan