2013-08-13 28 views
10

Khi sử dụng apply trên một data.frame, đối số được (ngầm) được chuyển đổi thành ký tự. Một ví dụ:Cách tránh chuyển đổi ký tự ngầm khi sử dụng áp dụng trên khung dữ liệu

df <- data.frame(v=1:10, t=1:10) 
df <- transform(df, t2 = as.POSIXlt(t, origin = "2013-08-13")) 
class(df$t2[1]) 
## [1] "POSIXct" "POSIXt" (correct) 

nhưng:

apply(df, 1, function(y) class(y["t2"])) 
## [1] "character" "character" "character" "character" "character" "character" 
## [7] "character" "character" "character" "character" 

Có cách nào để tránh chuyển đổi này? Hoặc tôi có phải luôn chuyển đổi qua as.POSIXlt(y["t2"]) không?

chỉnh sửa
df của tôi có 2 timestamps (nói, t2 và t3) và một số lĩnh vực khác (ví dụ, v1, v2). Đối với mỗi hàng có t2, tôi muốn tìm k (ví dụ: 3) hàng có t3 gần nhất, nhưng thấp hơn t2 (và cùng v1) và trả lại số liệu thống kê trên v2 từ các hàng này (ví dụ: mức trung bình). Tôi đã viết một hàm f (t2, v1, df) và chỉ muốn áp dụng nó trên tất cả các hàng bằng cách sử dụng apply(df, 1, function(x) f(y["t2"], y["v1"], df). Có cách nào tốt hơn để làm những điều như vậy trong R?

+5

Câu trả lời thực sự ở đây là bạn không nên sử dụng 'áp dụng' trên một khung dữ liệu. Bạn đang cố làm gì vậy? – joran

+7

* Chuyển đổi * xảy ra vì 'data.frame' của bạn đang bị ép buộc thành' ma trận'. –

+0

Mỗi lần chỉnh sửa của bạn, bạn thực sự có hai câu hỏi khác nhau (IMO). Tôi muốn nói câu hỏi thứ hai (Chỉnh sửa của bạn) với một tập dữ liệu thích hợp, những gì bạn đã thử và đầu ra mong muốn của bạn. –

Trả lời

4

Hãy quấn lên nhiều ý kiến ​​vào một lời giải thích.

  1. việc sử dụng apply chuyển đổi data.frame thành matrix. Điều này có nghĩa là lớp hạn chế ít nhất sẽ được sử dụng. Ít nhất hạn chế trong trường hợp này là ký tự.
  2. Bạn đang cung cấp đối số 1 tới apply 's MARGIN. Điều này áp dụng theo hàng và làm cho bạn thậm chí còn tồi tệ hơn khi bạn đang thực sự pha trộn các lớp học với nhau ngay bây giờ. Trong trường hợp này, bạn đang sử dụng apply được thiết kế cho ma trận và dữ liệu.frames trên vectơ. Đây không phải là công cụ thích hợp cho công việc.
  3. Trong ths trường hợp tôi muốn sử dụng lapply hoặc sapply như RMK chỉ ra để lấy các lớp học của cột t2 đơn như bên dưới:

Code:

df <- data.frame(v=1:10, t=1:10) 
df <- transform(df, t2 = as.POSIXlt(t, origin = "2013-08-13")) 

sapply(df[, "t2"], class) 
lapply(df[, "t2"], class) 

## [[1]] 
## [1] "POSIXct" "POSIXt" 
## 
## [[2]] 
## [1] "POSIXct" "POSIXt" 
## 
## [[3]] 
## [1] "POSIXct" "POSIXt" 
## 
## . 
## . 
## . 
## 
## [[9]] 
## [1] "POSIXct" "POSIXt" 
## 
## [[10]] 
## [1] "POSIXct" "POSIXt" 

Nói chung bạn chọn các gia đình apply phù hợp với công việc. Thường thì cá nhân tôi sử dụng lapply hoặc vòng lặp for để hành động trên các cột cụ thể hoặc tập hợp các cột tôi muốn bằng cách lập chỉ mục ([, ]) và sau đó tiếp tục với apply. Câu trả lời cho vấn đề này thực sự sôi xuống để xác định những gì bạn muốn thực hiện, yêu cầu là apply công cụ thích hợp nhất và tiến hành từ đó.

Tôi có thể cung cấp số blog post này làm hướng dẫn tuyệt vời về những gì khác nhau của apply họat động chức năng.

+1

Bài đăng trên blog tuyệt vời, nhưng tôi nghĩ nó không giải quyết được vấn đề của tôi. 'by' nên được sử dụng cho các khung dữ liệu, nhưng tôi cần nhiều hơn là chỉ nhóm theo v1. –

0

Hãy thử:

sapply(df, function(y) class(y["t2"])) 

$v 
[1] "integer" 

$t 
[1] "integer" 

$t2 
[1] "POSIXct" "POSIXt" 
+1

Cảm ơn, nhưng tôi cần áp dụng chức năng của mình cho mỗi hàng của khung dữ liệu. Kết quả là, tôi muốn có nhiều hàng như trong khung dữ liệu gốc. –

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