2015-04-26 18 views
5

Tôi cố gắng để tạo ra một cột trong một tbl_df đó là một số nguyên ngẫu nhiên từ 0 hoặc 1. Đây là mã tôi đang sử dụng:dplyr: Integer lấy mẫu trong vòng đột biến

library(dplyr) 
set.seed(0) 

#Dummy data.frame to test 
df <- tbl_df(data.frame(x = rep(1:3, each = 4))) 

#Generate the random integer column 
df_test = df %>% 
    mutate(pop=sample(0:1, 1, replace=TRUE)) 

Nhưng điều này dường như không làm việc theo cách tôi mong đợi. Trường tôi tạo ra dường như là tất cả các số không. Có phải vì câu lệnh trong phạm vi mutate được đánh giá song song và do đó kết thúc bằng cách sử dụng cùng một hạt giống cho lần rút ngẫu nhiên đầu tiên?

df_test 
Source: local data frame [12 x 2] 

    x pop 
1 1 0 
2 1 0 
3 1 0 
4 1 0 
5 2 0 
6 2 0 
7 2 0 
8 2 0 
9 3 0 
10 3 0 
11 3 0 
12 3 0 

Tôi đang phá vỡ đầu của mình trong vài giờ qua. Bất kỳ ý tưởng lỗ hổng trong kịch bản của tôi là gì?

+1

Sử dụng 'mẫu (0: 1, 12, thay thế = TRUE) ' – DatamineR

+6

Hoặc' mẫu (0: 1, n(), thay thế = TRUE) ' –

Trả lời

7

Cách mã của bạn được viết, bạn chỉ định một giá trị duy nhất (kết quả của phép vẽ ngẫu nhiên) cho toàn bộ vectơ (điều này được gọi là "tái chế vector").

Giải pháp tốt nhất trong trường hợp này là câu trả lời Steven Beaupré của, tạo ra một vector ngẫu nhiên chiều dài của data.frame của bạn:

df %>% 
    mutate(pop = sample(0:1, n(), replace = TRUE)) 

Thông thường, nếu bạn muốn áp dụng một chức năng hàng-by- hàng trong dplyr - như bạn nghĩ sẽ xảy ra ở đây - bạn có thể sử dụng rowwise(), mặc dù trong ví dụ này, nó không bắt buộc.

Dưới đây là một ví dụ về rowwise():

df2 <- data.frame(a = c(1,3,6), b = c(2,4,5)) 

df2 %>% 
    mutate(m = max(a,b)) 

    a b m 
1 1 2 6 
2 3 4 6 
3 6 5 6 

df2 %>% 
    rowwise() %>% 
    mutate(m = max(a,b)) 

    a b m 
1 1 2 2 
2 3 4 4 
3 6 5 6 

Kể từ rowwise nhóm dữ liệu theo từng hoạt động hàng có tiềm năng chậm hơn mà không bất kỳ nhóm. Do đó, tốt hơn hết là nên sử dụng các hàm vectơ bất cứ khi nào có thể thay vì vận hành từng hàng một.


Benchmarking:

Cách tiếp cận với rowwise() là khoảng 30x chậm:

library(microbenchmark) 
df <- tbl_df(data.frame(x = rep(1:1000, each = 4))) 
bench <- microbenchmark(
    vectorized = df2 <- df %>% mutate(pop = sample(0:1, n(), replace = TRUE)), 
    rowwise = df2 <- df %>% rowwise() %>% mutate(pop = sample(0:1, 1, replace = TRUE)), 
    times = 1000 
) 

options(microbenchmark.unit="relative") 
print(bench) 
autoplot(bench) 

Unit: relative 
     expr  min  lq  mean median  uq  max neval 
vectorized 1.00000 1.00000 1.00000 1.00000 1.00000 1.0000 1000 
    rowwise 42.53169 42.29486 36.94876 33.70456 34.92621 71.7682 1000 
+0

Tính năng này hoạt động tốt. Vì vậy, biểu thức trong 'mutate' không được đánh giá cho mỗi hàng không có toán tử này? Vì vậy, có một số hình thức numpy như phát sóng xảy ra với 'mutate'? – sriramn

+0

Chính xác. Tôi đã thêm một ví dụ minh họa về một ứng dụng điển hình hơn của 'rowwise()'. –

+0

'rowwise' không cần thiết trong trường hợp này. Thay vào đó, cách tiếp cận trong nhận xét của Steven đối với câu hỏi sẽ là tốt nhất theo ý kiến ​​của tôi. –

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