2015-01-08 18 views
6

Tôi đang phát triển một mô hình dự báo mức sinh hoàn thành cho một nhóm tuổi. Tôi hiện đang có một khung dữ liệu như thế này, nơi các hàng là lứa tuổi và các cột là năm. Giá trị trong mỗi ô là độ tuổi theo độ tuổi cụ thể cho năm đó:Trong R, chuyển đổi đường chéo khung dữ liệu thành các hàng

> df1 
    iso3 sex age fert1953 fert1954 fert1955 
14 AUS female 13 0.000 0.00000 0.00000 
15 AUS female 14 0.000 0.00000 0.00000 
16 AUS female 15 13.108 13.42733 13.74667 
17 AUS female 16 26.216 26.85467 27.49333 
18 AUS female 17 39.324 40.28200 41.24000 

Tuy nhiên, điều tôi muốn là mỗi hàng là một nhóm. Bởi vì các hàng và cột đại diện cho các năm riêng lẻ, nên có thể thu thập dữ liệu nhóm bằng cách lấy đường chéo. Tôi đang tìm kiếm một kết quả như thế này:

> df2 
    iso3 sex ageIn1953 fert1953 fert1954 fert1955 
14 AUS female  13 0.000 0.00000 13.74667 
15 AUS female  14 0.000 13.42733 27.49333 
16 AUS female  15 13.108 26.85467 41.24000 
17 AUS female  16 26.216 40.28200 [data..] 
18 AUS female  17 39.324 [data..] [data..] 

Dưới đây là khung df1 dữ liệu:

df1 <- structure(list(iso3 = c("AUS", "AUS", "AUS", "AUS", "AUS"), sex = c("female", 
"female", "female", "female", "female"), age = c(13, 14, 15, 
16, 17), fert1953 = c(0, 0, 13.108, 26.216, 39.324), fert1954 = c(0, 
0, 13.4273333333333, 26.8546666666667, 40.282), fert1955 = c(0, 
0, 13.7466666666667, 27.4933333333333, 41.24)), .Names = c("iso3", 
"sex", "age", "fert1953", "fert1954", "fert1955"), class = "data.frame", row.names = 14:18) 

EDIT:

Đây là giải pháp tôi cuối cùng sử dụng. Nó dựa trên câu trả lời của David, nhưng tôi cần phải làm điều này cho mỗi cấp độ iso3.

df.ls <- lapply(split(f3, f = f3$iso3), FUN = function(df1) { 
    n <- ncol(df1) - 4 
    temp <- mapply(function(x, y) lead(x, n = y), df1[, -seq_len(4)], seq_len(n)) 
    return(cbind(df1[seq_len(4)], temp)) 
}) 
f4 <- do.call("rbind", df.ls) 
+0

Bạn chỉ muốn tụt bạn tập dữ liệu? –

+0

Có, nhưng tôi nghĩ điều đó sẽ rất cồng kềnh. Tôi đang làm việc này cho 188 quốc gia trên 50 năm. Nếu bạn có thể nghĩ ra một cách tốt để làm điều đó, nó có thể là một giải pháp tốt đẹp. – rsoren

Trả lời

4

tôi đã không kiểm tra tốc độ, nhưng data.tablev1.9.5, thời gian gần đây thực hiện một (viết bằng C) chức năng dẫn/lag mới gọi là shift

Vì vậy, cho các cột mà bạn muốn thay đổi, bạn có thể có khả năng sử dụng nó kết hợp với mapply, ví dụ

library(data.table) 
n <- ncol(df1) - 4 # the number of years - 1 
temp <- mapply(function(x, y) shift(x, n = y, type = "lead"), df1[, -seq_len(4)], seq_len(n)) 
cbind(df1[seq_len(4)], temp) # combining back with the unchanged columns 
# iso3 sex age fert1953 fert1954 fert1955 
# 14 AUS female 13 0.000 0.00000 13.74667 
# 15 AUS female 14 0.000 13.42733 27.49333 
# 16 AUS female 15 13.108 26.85467 41.24000 
# 17 AUS female 16 26.216 40.28200  NA 
# 18 AUS female 17 39.324  NA  NA 

chỉnh sửa: Bạn có thể dễ dàng cài đặt sự phát triển phiên bản của data.table từ GitHub sử dụng

library(devtools) 
install_github("Rdatatable/data.table", build_vignettes = FALSE) 

Dù bằng cách nào, nếu bạn muốn dplyr, ở đây đi

library(dplyr) 
n <- ncol(df1) - 4 # the number of years - 1 
temp <- mapply(function(x, y) lead(x, n = y), df1[, -seq_len(4)], seq_len(n)) 
cbind(df1[seq_len(4)], temp) 
# iso3 sex age fert1953 fert1954 fert1955 
# 14 AUS female 13 0.000 0.00000 13.74667 
# 15 AUS female 14 0.000 13.42733 27.49333 
# 16 AUS female 15 13.108 26.85467 41.24000 
# 17 AUS female 16 26.216 40.28200  NA 
# 18 AUS female 17 39.324  NA  NA 
+0

Điều này có vẻ tuyệt vời. Thật không may v1.9.4 là phiên bản mới nhất của data.table trên CRAN và tôi gặp sự cố khi tải xuống phiên bản dev từ GitHub. Rõ ràng đây là một vấn đề phổ biến trên Windows. Tôi đang sử dụng hàm '' 'lead()' '' của dplyr thay thế; Tôi nghĩ rằng nó sẽ làm việc ... – rsoren

+0

Xem chỉnh sửa của tôi sau đó –

+0

Tôi đã thực hiện một điều chỉnh cho tài khoản cho thực tế rằng điều này cần phải được thực hiện riêng cho mỗi giá trị của '' 'iso3''' (xem chỉnh sửa của tôi ở trên). Vấn đề với data.table là tôi nhận được một lỗi "Command failed (1)", điều này làm cho nó khó khăn hơn so với '' 'install_github()' '' thông thường. Có một liên kết về điều này trên trang cài đặt của data.table. Cảm ơn nhiều! – rsoren

1

Đây là một cách tiếp cận cơ sở R:

df1[,5:ncol(df1)] <- mapply(function(x, y) {vec.list <- df1[-1:-y, x] 
         length(vec.list) <- nrow(df1) 
         vec.list}, 
         x=5:ncol(df1), y=1:(ncol(df1)-4)) 
df1 
# iso3 sex age fert1953 fert1954 fert1955 
#14 AUS female 13 0.000 0.00000 13.74667 
#15 AUS female 14 0.000 13.42733 27.49333 
#16 AUS female 15 13.108 26.85467 41.24000 
#17 AUS female 16 26.216 40.28200  NA 
#18 AUS female 17 39.324  NA  NA 
Các vấn đề liên quan