2013-02-09 19 views
5

Tôi có một khung dữ liệu với các giá trị giả này và tôi muốn thực hiện hồi quy lm trên chúng. Một trong các biến là biến số liên tục được nhóm như được hiển thị bên dướiChuyển đổi một biến liên tục được nhóm thành các hàng trong R

df <- data.frame("y" = c(10, 11, 12, 13, 14), 
       "x" = as.factor(c("100-102", "103-105", "106-108", "109-111", "112-114"))) 

Tôi muốn khôi phục y ~ x, Một cách là thay thế các yếu tố x bằng giá trị số trung bình của chúng. Điều này có thể dễ dàng thực hiện bằng cách sử dụng cụm từ thông dụng.

Một cách khác là tạo ra các hàng bổ sung và mở rộng bộ dữ liệu của bạn để nó trông như thế này

data.frame("y" = c(10, 10, 10, 11, 11, 11......), 
      "x" = c(100, 101, 102, 103, 104, 105......)) 

Có một chức năng mà sẽ làm điều này?

Tôi đang nghĩ đến việc tạo các biến bổ sung như x1, x2, x3 và sau đó sử dụng gói reshape2 để chuyển đổi x cột thành hàng.

Trả lời

4

Giải pháp data.table. Điều này cũng nên thực sự nhanh trên số lớn của data.frame.

require(data.table) 
dt <- data.table(df, key="y") 
dt[, list(x=seq(sub("-.*$", "", x), sub(".*-", "", x))),by=y] 

Nếu bạn có nhiều cột và bạn không muốn mỗi kết hợp khi tách theo cột x, thì đây là mã để sử dụng:

require(data.table) 
dt <- data.table(df) 
# get all column names except "x" 
key.cols <- setdiff(names(df), "x") 
# set the data.table columns to key.cols 
setkeyv(dt, key.cols) 
dt.out <- dt[, list(x=seq(sub("-.*$", "", x), sub(".*-", "", x))), by = key.cols] 

Điều này sẽ cho bạn biết những gì bạn mong đợi.

+0

đây là một giải pháp đơn giản và thanh lịch. Cảm ơn. btw nó sẽ mở rộng như thế nào với bộ dữ liệu với nhiều cột. Ví dụ của tôi là một dataframe giả. dataframe thực tế của tôi có nhiều cột số và cột một yếu tố – MySchizoBuddy

+0

chỉ một cột để tách nhưng tập dữ liệu có nhiều cột, vì vậy các hàng cho tất cả các cột khác sẽ được lặp lại cùng với y – MySchizoBuddy

+1

hoạt động tốt với rất ít dòng mã. Cảm ơn – MySchizoBuddy

2
require(stringr) 
require(foreach) 

foreach(i=1:nrow(df), .combine=rbind) %do% { 
    s <- as.numeric(str_extract_all(df$x[i], "[0-9]+")[[1]]) 
    data.frame(y=rep(df$y[i], s[2]-s[1]+1), x=seq(s[1], s[2])) 
} 

Nếu bạn data.frame thực sự lớn, bạn có thể đi cùng với %dopar%.

+0

nhanh chóng. không lớn chỉ 2500 hàng. – MySchizoBuddy

+0

'% do%' và '% dopar%' được cung cấp bởi gói 'foreach'. – redmode

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