2016-07-23 53 views
1

我有創造一個過渡矩陣,下面的數據集的一個問題是我的工作,在一個變量

Name  Rating ID DATE(YYYYmmdd) 
@0CC  1 71476 20000704  
@0CC  1 71476 20001204  
@0RM  1 73565 20000919  
@0RM  2 49960 20000131  
@0RM  1 44457 20001214  
@0RM  1 59451 20001023  
@0TL  2 73862 20001212  
@0TL  3 19824 20000929  
@0TL  1 70970 20001211  
@0TL  3 48061 20000627   
@0TL  1 48061 20001227  
@1AJ  1 58875 20001214  
@1AJ  3 56014 20001214  
@1AJ  3 47340 20001214  
@1AJ  3 19813 20001214  
@1AL  1 44416 20000517  
@1AL  4 59184 20000801  
@1AL  3 59184 20000413  
@1AL  4 72832 20001127  
@1AL  1 52718 20000621  
@1AL  2 59184 20000707  
@1AL  3 73568 20001130  
@1AL  3 72832 20001211  
@1AL  3 44416 20000303  

我想要做的就是創建每個獨特元素的過渡矩陣每一個獨特的名字,我想比較身份證,如果身份證匹配,我會看看日期,比較晚的日期和以前的日期,如果收視率相似,我會忽略,但如果收視率不同,我會喜歡計算移動次數。

E.g在前兩行中,查看名稱@OCC,ID變量匹配並查看評分,它們類似,那麼我不會將其添加到計數中。然而,在@ 1AL中,ID變量匹配三次,查看發生的日期,分別有三個日期20000413,20000707和20000801,其評分分別爲3,2和4。隨着評分從3再次變爲2,我想將其記錄在以下格式的轉換矩陣中。

From 1 2 3 4 5 (to) 
    1 
    2   1 
    3  1 
    4 
    5 

是相當新的這個數據管理的事情,這就是我,

for(i in unique(dataset$Name) 
if dataset[,3]=dataset[,3] 

,我不認爲第二行是甚至還可以直接。我真的很困難,並會感謝我能得到的任何建議。

回答

1

花了一些時間,但我想我找到了一個解決方案,您的問題:

轉換成data.table

install.packages("data.table") #if not installed already 
require(data.table) 
### DT: your data.frame 
### e.g. copy and 
#DT <- read.table("clipboard",header = T) 
DT <- as.data.table(DT) # convert into data.table 
setkey(DT, Name, DATE) 
#this shows some temporary result: 
DT[, print(Rating), by = list(Name, ID)] 
    # [1] 1 1 
    # [1] 1 
    # [1] 2 
    # [1] 1 
    # [1] 1 
    # [1] 2 
    # [1] 3 
    # [1] 1 
    # [1] 3 1 
    # [1] 1 
    # [1] 3 
    # [1] 3 
    # [1] 3 
    # [1] 1 3 
    # [1] 4 3 2 
    # [1] 4 3 
    # [1] 1 
    # [1] 3 

一個問題是,data.table不返回每個子集的矢量(據我所知)。因此,解決方案是將單個數字的數字轉換爲更長的數字並稍後將其轉換回來。

獲得收視率

setVal <- function(vec){ 
    res <- 0 
    for (i in 1:length(vec)){ 
    res <- res + vec[i] * 10^(length(vec)-i) 
    } 
    return(as.integer(res)) 
} 
#save above shown result in vector. 
DT <- DT[, R:=setVal(Rating), by = list(Name, ID)] 
DT #the result is not as desired because e.g. 324 occurs 3 times (at each row which leads to 324), 11 occurs 2 times (at both rows contributing to 11). 
    # Name Rating ID DATE.YYYYmmdd. R 
    # 1: @0CC  1 71476  20000704 11 
    # 2: @0CC  1 71476  20001204 11 
    # 3: @0RM  2 49960  20000131 2 
    # 4: @0RM  1 73565  20000919 1 
    # 5: @0RM  1 59451  20001023 1 
    # 6: @0RM  1 44457  20001214 1 
    # 7: @0TL  3 48061  20000627 31 
    # 8: @0TL  3 19824  20000929 3 
    # 9: @0TL  1 70970  20001211 1 
    # 10: @0TL  2 73862  20001212 2 
    # 11: @0TL  1 48061  20001227 31 
    # 12: @1AJ  1 58875  20001214 1 
    # 13: @1AJ  3 56014  20001214 3 
    # 14: @1AJ  3 47340  20001214 3 
    # 15: @1AJ  3 19813  20001214 3 
    # 16: @1AL  3 44416  20000303 31 
    # 17: @1AL  3 59184  20000413 324 
    # 18: @1AL  1 44416  20000517 31 
    # 19: @1AL  1 52718  20000621 1 
    # 20: @1AL  2 59184  20000707 324 
    # 21: @1AL  4 59184  20000801 324 
    # 22: @1AL  4 72832  20001127 43 
    # 23: @1AL  3 73568  20001130 3 
    # 24: @1AL  3 72832  20001211 43 
#The result has to be filtered by unique pairs of Name and ID. 
R <- DT[,unique(R), by = list(Name, ID)]$V1 
#[1] 11 2 1 1 1 31 3 1 2 1 3 3 3 31 324 1 43 3 

變換結果爲轉移矩陣

有可能是一些比較容易R兌換成個位數,計數的值,並把它們變成一個矩陣的方式,但這是我想到的:

TransitionMatrix <- function(col, ncol = 5){ 
    intoMat <- function(Mat, vec){ 
    if(length(vec)>1){ 
     for (i in 1:(length(vec)-1)){ 
     if (vec[i] != vec[i+1]){ 
      Mat[vec[i], vec[i+1]] <- Mat[vec[i], vec[i+1]] + 1 
     } 
     } 
    } 
    return(Mat) 
    } 
    Mat <- matrix(0, ncol = ncol, nrow = ncol) 
    for (j in 1:length(col)){ 
    L <- nchar(as.character(j)) 
    if(L>1){ 
     values <- as.numeric(unlist(strsplit(as.character(col[j]),""))) 
     Mat <- intoMat(Mat, values) 
    } 
    } 
    return(Mat) 
} 

TransitionMatrix(R, 5) 
    #  [,1] [,2] [,3] [,4] [,5] 
    # [1,] 0 0 2 0 0 
    # [2,] 0 0 0 0 0 
    # [3,] 2 3 0 0 0 
    # [4,] 0 0 5 0 0 
    # [5,] 0 0 0 0 0 

該解決方案的侷限性是當收視率高於9並且有2位數字時。

+0

你好,感謝您的解答,我很感激。首先,我添加了一個setkey根據日期重新排列表,根據日期重新排列數據表。我的評論突然出現了,這使我無法將自己的代碼放在評論部分,這令人討厭,我已經通過編輯您提供的解決方案添加了它,希望您不要介意。如果你可以進一步向我解釋,我真的不知道代碼的獲得評級部分發生了什麼?然而,似乎有一個雙重計數,該soln是不正確的。 – Donkeykongy

+0

是的,它提供了預期的結果。然而,現在的問題是將其轉換爲一個可用的向量,如上所述,我被卡住了。 @Phann – Donkeykongy

+0

對於註釋中的代碼,請在[雙反引號]代碼[雙反引號]之間插入。對於*獲得收視率*部分,我想將每個子集的輸出保存到一個(整數)變量中,因爲我不知道如何爲每個子集返回一個矢量。所以我真正想要的是一些* object *,它包含了可以用'print'看到的東西。此處的解決方法是將單個數字的數字保存爲一個整數,其中此整數的每個數字都是此*子集向量*的一個元素。 – Phann