Re: [問題] 資料轉換

看板R_Language作者 (天)時間9年前 (2015/11/15 14:16), 9年前編輯推噓0(000)
留言0則, 0人參與, 最新討論串6/6 (看更多)
關於使用迴圈,我有一點想法可以參考看看 最下方補上不用for-loop的方法 # data generation set.seed(300) N = 100 df = data.frame(x = sample(1:100, N, TRUE), y = runif(N), z = sample(0:1, N, TRUE, prob = c(0.4, 0.6))) # 計算重複的長度,已取得我需要preallocate多大的矩陣 zLength = rle(df$z)$lengths # zLength: # [1] 4 3 1 1 2 1 2 1 1 2 2 1 4 3 1 1 2 1 1 2 1 3 1 2 # [25] 1 3 1 3 1 2 2 2 1 2 1 2 2 5 4 2 10 3 2 1 1 2 2 2 # 超過五的部分都要多加一行 outRow = length(zLength) + zLength[zLength > 5] %/% 5 + as.numeric(zLength[(zLength > 5)] %% 5 > 0) - sum(zLength > 5) # outRow: # [1] 49 (只有一個超過5,只需要多一行) # create output matrix and preallocate outMat = matrix(NA, outRow, 5) # 上一個值 lastValue = 1 - df$z[1] j = 0 # row編號 k = 0 # col編號 rowNamesVec = vector('numeric', outRow) # 存rownames for (i in 1:nrow(df)) { if (df$z[i] != lastValue) # 如果跟上一個值不相同就跑這塊 { j = j + 1 # 移到下一個row k = 1 # col回到1 (新的row) outMat[j, k] = df$x[i] # assign進去output的matrix lastValue = df$z[i] # 把這次的z存起來做下一次的判斷 rowNamesVec[j] = df$z[i] # 存下這次的z以assign rownames } else # 如果跟上一個值相同就跑這塊 { k = k + 1 # 移到下一個column if (k > 5) # 如果k超過五就移到下一個row 並且存進rownames { j = j + 1 k = 1 rowNamesVec[j] = df$z[i] } outMat[j, k] = df$x[i] # assign進去output的matrix } } rownames(outMat) = rowNamesVec # 賦予rownames outMat結果: [,1] [,2] [,3] [,4] [,5] 0 92 77 81 74 NA 1 69 2 76 NA NA 0 50 NA NA NA NA 1 47 NA NA NA NA 0 91 95 NA NA NA 1 32 NA NA NA NA 0 80 59 NA NA NA 1 66 NA NA NA NA 0 99 NA NA NA NA 1 89 67 NA NA NA 0 64 51 NA NA NA 1 99 NA NA NA NA 0 50 47 7 10 NA 1 3 53 90 NA NA 0 70 NA NA NA NA 1 23 NA NA NA NA 0 52 72 NA NA NA 1 93 NA NA NA NA 0 39 NA NA NA NA 1 10 46 NA NA NA 0 40 NA NA NA NA 1 76 62 78 NA NA 0 37 NA NA NA NA 1 1 74 NA NA NA 0 88 NA NA NA NA 1 38 87 56 NA NA 0 35 NA NA NA NA 1 13 75 38 NA NA 0 80 NA NA NA NA 1 60 100 NA NA NA 0 91 59 NA NA NA 1 47 89 NA NA NA 0 86 NA NA NA NA 1 5 37 NA NA NA 0 63 NA NA NA NA 1 65 30 NA NA NA 0 22 60 NA NA NA 1 44 52 79 78 64 0 86 25 7 51 NA 1 31 42 NA NA NA 0 92 13 68 82 19 0 21 95 42 24 66 1 67 91 44 NA NA 0 92 31 NA NA NA 1 84 NA NA NA NA 0 52 NA NA NA NA 1 75 40 NA NA NA 0 68 17 NA NA NA 1 60 20 NA NA NA ## no for loop continueLength = rle(df$z)$lengths splitGroup = rep(1:length(continueLength), continueLength) outMat = lapply(split(df, splitGroup), function(subdf){ if (length(subdf$x) <= 5) c(subdf$x, rep(NA, 5 - length(subdf$x))) else { numRows = length(subdf$x) %/% 5 + as.numeric(length(subdf$x) %% 5 > 0) NAnum = 5 - length(subdf$x)%%5 matrix(c(subdf$x,rep(NA,NAnum)), numRows, 5, byrow = TRUE) } }) outMat = do.call(rbind, outMat) rownames(outMat)[nchar(rownames(outMat)) != 0] = rle(df$z)$values ※ 引述《Rose9305 (台產零零柒)》之銘言: : [問題類型]: : 程式諮詢(我想用R 做某件事情,但是我不知道要怎麼用R 寫出來) : [軟體熟悉度]: : 新手(沒寫過程式,R 是我的第一次) : [問題敘述]: : 資料轉換 : 我有個資料csv檔,裡面內容大概如下 : : x y z : 55 0.2 1 : 44 0.6 1 : 78 0.7 0 : 46 0.8 0 : 98 0.9 1 : 47 0.4 1 : 46 0.5 1 : 想(限)用 ''for 迴圈''轉換成只取x,z並以z重排x,如下: : 1 55 44 : 0 78 46 : 1 98 47 46 : 把 z=1 排成一列,一遇到 z=0 又排成一列,再讀到1又排成一列這樣下去 : 不知道要如何用for迴圈來把資料轉換成上述。 : 抱歉,再問下因實際DATA比較多,因此可以每列只列5個值然後換下一行嗎? : 一樣用1,0排, : 像是 1 55 44 67 78 46 : 1 47 48 99 78 16 : 0 48 49 77 66 55 : 1 76 78 79 88 99 這樣排列呢?? -- -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 180.218.154.163 ※ 文章網址: https://www.ptt.cc/bbs/R_Language/M.1447568201.A.2D7.html ※ 編輯: celestialgod (180.218.154.163), 11/15/2015 14:20:35 ※ 編輯: celestialgod (180.218.154.163), 11/15/2015 14:24:46 ※ 編輯: celestialgod (180.218.154.163), 11/15/2015 14:37:21
文章代碼(AID): #1MI2D9BN (R_Language)
討論串 (同標題文章)
文章代碼(AID): #1MI2D9BN (R_Language)