2012-10-23 35 views
5

Tôi đang cố gắng viết một chương trình có khung dữ liệu lớn và thay thế từng cột giá trị theo tần số tích lũy của các giá trị đó (sắp xếp tăng dần). Ví dụ, nếu cột của giá trị là: 5, 8, 3, 5, 4, 3, 8, 5, 5, 1. Sau đó các tần số tương đối và tích lũy là:thay thế hiệu quả khung dữ liệu với tần số tích lũy

  • 1: rel_freq = 0,1, cum_freq = 0,1
  • 3: rel_freq = 0,2, cum_freq = 0,3
  • 4: rel_freq = 0,1, cum_freq = 0,4
  • 5: rel_freq = 0,4, cum_freq = 0,8
  • 8: rel_freq = 0,2, cum_freq = 1.0

Sau đó, đồng gốc lumn trở thành: 0.8, 1.0, 0.3, 0.8, 0.4, 0.3, 1.0, 0.8, 0.8, 0.1

Đoạn mã sau thực hiện thao tác này một cách chính xác, nhưng quy mô kém có thể do vòng lặp lồng nhau. Bất kỳ ý tưởng làm thế nào để thực hiện nhiệm vụ này hiệu quả hơn?

mydata = read.table(.....) 

totalcols = ncol(mydata) 
totalrows = nrow(mydata) 

for (i in 1:totalcols) { 
    freqtable = data.frame(table(mydata[,i])/totalrows) # create freq table 
    freqtable$CumSum = cumsum(freqtable$Freq) # calc cumulative freq 

    hashtable = new.env(hash=TRUE) 
    nrows = nrow(freqtable) 

    # store cum freq in hash 
    for (x in 1:nrows) { 
     dummy = toString(freqtable$Var1[x]) 
     hashtable[[dummy]] = freqtable$CumSum[x] 
    } 

    # replace original data with cum freq 
    for (j in 1:totalrows) { 
     dummy = toString(mydata[j,i]) 
     mydata[j,i] = hashtable[[dummy]] 
    } 
} 
+0

Bạn có thể cho chúng ta một [ví dụ tái sản xuất] (http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-exa mple)? –

Trả lời

2

này xử lý một cột duy nhất mà không for -loop:

R> x <- c(5, 8, 3, 5, 4, 3, 8, 5, 5, 1) 
R> y <- cumsum(table(x)/length(x)) 
R> y[as.character(x)] 
    5 8 3 5 4 3 8 5 5 1 
0.8 1.0 0.3 0.8 0.4 0.3 1.0 0.8 0.8 0.1 
+0

Câu trả lời hay! Chương trình của tôi có quy mô tốt hơn nhiều khi sử dụng mã này. Cảm ơn! – user1769120

1

Dưới đây là một cách. Sử dụng một khung dữ liệu với hai biến mỗi chứa ví dụ dữ liệu của bạn

d <- data.frame(var1 = c(5, 8, 3, 5, 4, 3, 8, 5, 5, 1), 
       var2 = c(5, 8, 3, 5, 4, 3, 8, 5, 5, 1)) 

sử dụng một chức năng đơn giản để

  1. tạo ra cumsum() của tỷ lệ tương đối do table(x)/length(x), sau đó
  2. match() các quan sát trong một biến với tên của bảng tổng tích lũy, sau đó
  3. sử dụng các đối sánh id để chọn từ bảng tổng tích lũy (và bỏ tên nó)

một chức năng như vậy là:

f <- function(x) { 
    tab <- cumsum(table(x)/length(x)) 
    ind <- match(x, as.numeric(names(tab))) 
    unname(tab[ind]) 
} 

Trên thực tế chúng tôi sử dụng lapply() và ép buộc để một khung dữ liệu:

out <- data.frame(lapply(d, f)) 
out 

mang đến cho:

R> out 
    var1 var2 
1 0.8 0.8 
2 1.0 1.0 
3 0.3 0.3 
4 0.8 0.8 
5 0.4 0.4 
6 0.3 0.3 
7 1.0 1.0 
8 0.8 0.8 
9 0.8 0.8 
10 0.1 0.1 
+0

Cảm ơn, tôi sẽ thử. – user1769120

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