2017-07-14 40 views
0

我想寫一個循環,比較組DT/DF的「中間」值與其前面的列。當循環遇到值大於相應'中間'列值的列時,將該列名稱打印到名爲mIncome的向量,並跳過剩餘的列並繼續循環中的下一次迭代。但是,循環似乎並沒有結束。重複循環有零替換

我最終想要一個矢量,其中包含第一列的名稱,其值大於相應行的「中間」值。我知道,不建議循環,但如果任何人有任何建議...

groups <- dput(groups) 
structure(list(one = c(33, 32, 161, 93, 69, 74, 24, 24, 21, 25 
), two = c(53, 68, 164, 111, 96, 125, 35, 103, 39, 25), three = c(109, 
97, 188, 159, 160, 169, 53, 149, 106, 34), four = c(114, 161, 
214, 183, 302, 190, 86, 193, 155, 62), five = c(120, 183, 237, 
241, 384, 257, 105, 388, 174, 62), six = c(169, 269, 264, 262, 
633, 293, 195, 489, 239, 122), seven = c(209, 351, 351, 279, 
717, 326, 243, 652, 291, 152), eight = c(214, 393, 357, 346, 
769, 336, 255, 672, 353, 197), nine = c(238, 459, 365, 364, 816, 
336, 336, 722, 363, 197), middle = c(119, 230, 182, 182, 408, 
168, 168, 361, 182, 98)), .Names = c("one", "two", "three", "four", 
"five", "six", "seven", "eight", "nine", "middle"), class = c("data.table", 
"data.frame"), row.names = c(NA, -10L), .internal.selfref = <pointer: 0x00000000000b0788>) 




repeat{ 
    mIncome <- character(length = nrow(groups)) 

for(i in 1:(dim(groups)[1])){ 
    for(j in 1:(dim(groups)[2] - 1)){ 
     if(groups[i][[10]] < groups[i][[j]]){ # is middle value greater than... 
     mIncome[i] <- as.character(colnames(groups[, j - 1, with = FALSE])) 
     break 
     } else (print('no')) 
     } 
    } 
    mIncome 
} 

回答

1

有幾個問題。一,在文本你說

When the loop comes across a column that has a value larger than corresponding 'middle' column value

,但在你的代碼,你有

if(groups[i][[10]] > groups[i][[j]]){ # is middle value greater than...

所以,你想不想當值比中間大,或者中間是大於value ?

其次,當您發現自己使用多個嵌套for循環時,可能會有一種更簡單的方法。

我打算先做一個函數,然後將它應用到每一行。

appfunc <- function(x) { 
    if (!any(x[1:(length(x)-1)] > x[length(x)])) return("no") 
    names(groups)[which(x[1:(length(x)-1)] > x[length(x)])[1]] 
} 

讓我們解開它。該函數將從data.frame中通過x行,在這種情況下,我假設了groupsdata.frame。對於數據集中的第一行,x將是c(33, 55, 109, 114, 120, 169, 209, 214, 238, 119)。函數的第一行是檢查除了最後一個元素以外的任何x值是否大於最後一個元素,如果不是,則返回「no」。如果至少有一個值更大,則第二行將返回第一行,並返回該列的相應名稱。

因此,對於groups中的第一行,我們期望函數返回「五」。

現在,讓apply函數給groups的每一行。

apply(groups, 1, appfunc)

這裏的語法是非常簡單的。這只是說要將我們上面定義的appfunc應用於groups中的每一行。

輸出:

# [1] "five" "six" "three" "four" "six" "three" "six" "five" "six" "six" 
1

我只是說medclass[,j,with=FALSE],並應解決您的問題。這裏有一個解決方案

for(i in 1:(dim(medclass)[1])){ 
    for(j in 1:(dim(medclass)[2] - 1)){ 
    if(groups[i][[10]] > groups[i][[j]]){ # is middle value greater than... 
     mIncome[i] <- as.character(colnames(medclass[, j,with=FALSE])) 
     next 
    } else (print('no')) 
    } 
} 

解決方案與正確的指標:

for(i in 1:(dim(medclass)[1])){ 
    for(j in 1:(dim(medclass)[2] - 3)){ 
    if(groups[i][[10]] > groups[i][[j]]){ # is middle value greater than... 
     mIncome[i] <- as.character(colnames(medclass[, j+4,with=FALSE])) 
     next 
    } else (print('no')) 
    } 
} 

絕不這是一個有效的解決方案。一個有效的解決方案必須在那裏。

+0

我得到一個不同的錯誤:錯誤.subset2(X,I,確切=確切):下標出界。我必須打印什麼?我可以跳過else語句,並且爲每行打印真實條件(中間>其他列)? – user3067851