2016-04-25 17 views
10

Tôi đã vi phạm đầu của mình về việc dịch this question thành giải pháp data.table. (Để đơn giản, tôi sẽ sử dụng cùng một tập dữ liệu)
Khi V2 == "b Tôi muốn hoán đổi các cột giữa V1 <-> V3.Trao đổi giá trị giữa hai cột bằng cách sử dụng data.table

dt <- data.table(V1=c(1,2,4), V2=c("a","a","b"), V3=c(2,3,1)) 
#V1 V2 V3 
#1: 1 a 2 
#2: 2 a 3 
#3: 4 b 1 

Đoạn code dưới đây sẽ là giải pháp làm việc cho data.frame, tuy nhiên vì số lượng của sự thất vọng này đã cho tôi vì tôi đã sử dụng một data.table mà không nhận ra Tôi bây giờ cố gắng tìm ra một giải pháp cho data.table .

dt <- data.table(V1=c(1,2,4), V2=c("a","a","b"), V3=c(2,3,1)) 
df <- as.data.frame(dt) 
df[df$V2 == "b", c("V1", "V3")] <- df[df$V2 == "b", c("V3", "V1")] 
# V1 V2 V3 
#1 1 a 2 
#2 2 a 3 
#3 1 b 4 

Tôi đã thử viết một hàm lapply Looping qua danh sách trao đổi mục tiêu của tôi, cố gắng để thu hẹp vấn đề để chỉ thay thế một giá trị, cố gắng gọi tên cột theo những cách khác nhau nhưng tất cả đều không thành công.
Đây là nỗ lực gần nhất tôi đã quản lý để có được:

> dt[dt$V2 == "b", c("V1", "V3")] <- dt[dt$V2 == "b", c(V3, V1)] 
#Warning messages: 
#1: In `[<-.data.table`(`*tmp*`, dt$V2 == "b", c("V1", "V3"), value = c(1, : 
# Supplied 2 items to be assigned to 1 items of column 'V1' (1 unused) 
#2: In `[<-.data.table`(`*tmp*`, dt$V2 == "b", c("V1", "V3"), value = c(1, : 
# Supplied 2 items to be assigned to 1 items of column 'V3' (1 unused) 

Làm thế nào chúng ta có thể có được giải pháp data.table?

Trả lời

8

Chúng tôi có thể thử

dt[V2=="b", c("V3", "V1") := .(V1, V3)] 
+0

Tôi đoán sử dụng '.SD' nhanh hơn đi 'danh sách (V1, V3) '? – BenBarnes

+1

@BenBarnes Tôi đã không kiểm tra xem nó sẽ nhanh hơn, trông giống như 'danh sách (V1, V3)' sẽ là tốt quá. – akrun

+0

@eddi, những gì bạn có chống lại '.SDcols'? Tôi nghĩ rằng đó là giải pháp mạnh mẽ hơn trong trường hợp bạn có một vector của các cột được xác định trước. –

2

Đối với chỉ vui chơi giải trí. Giải pháp của @akruns rõ ràng vượt trội. Tôi lập luận rằng tôi có thể tạo ra một bản sao tạm thời, làm cho trao đổi có điều kiện, và sau đó xóa các bản sao tất cả sử dụng [.data.table hoạt động theo thứ tự:

dt[, tv1 := V1][V2=="b", V1 := V3][V2=="b", V3 := tv1][ , tv1 := NULL] 

> dt 
    V1 V2 V3 
1: 1 a 2 
2: 2 a 3 
3: 1 b 4 
+0

Điều này hoán đổi các giá trị sai! Có vẻ mát mẻ tho – Bas

+5

Ah, vâng, tôi đã trao đổi giá trị "a" thay vì giá trị "b". Có vẻ như không đáng để sửa vì nó sẽ rất chậm. Tôi chỉ đăng nó để mọi người có thể ném cà chua. –

+0

ít nhất là làm một giải pháp 'bitwXor' nếu bạn đang nhắm đến mục đích thú vị; không thích thú vì là – eddi

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