2011-04-01 99 views
2

我正在努力處理一些代碼。我可以非常低效地開展工作,但認爲必須有更好的解決方法。我想從幾個不同的變量編譯一個變量。在編碼變量中,「跳過」被編碼爲特定編號(例如「99」以下的示例)。我試圖根據這些變量中的10個創建總成本變量。用sapply幫助改進R編碼

這樣,我所做的工作由低效代碼:

var1 <- ifelse(data$v1<99, data$v1, 0) 
var2 <- ifelse(data$v2<99, data$v2, 0) 
... 
var10 <- ifelse(data$v1<99, data$v10, 0) 
sumvar <- var1 + var2 + var3 + var4 + var5 + var6 + var7 + var8 + var9 + var10 

我曾嘗試使用sapply命令,使這個多一點優雅,但沒有奏效。我只是想看看有人可以給我一些提示或幫助我爲什麼我的代碼失敗。我把它放到一個列表環境中(我認爲在嘗試像cbind這樣的其他人之後是正確的)並嘗試執行特定的調用,但出現錯誤。作爲示例代碼,我設置了以下內容:

set.seed(1234) 
data <- data.frame(x=rnorm(30), y=rnorm(30), z=rnorm(30)) 
data$x <- ifelse(data$x > 1, 99, data$x) 
data$y <- ifelse(data$y > 1, 99, data$y) 
data$z <- ifelse(data$z > 1, 99, data$z) 

t.list <- list(data$x, data$y, data$z) 

sumvar1 <- sapply(1:length(t.list), function(i){ 
    tempvar <- ifelse(t.list[i] !=99, t.list[i], 0) 
    sumvar1 <- sumvar1 + tempvar 
}) 

的問題是,當我嘗試我的實際代碼(或驗證碼),我得到:

Error in storage.mode(test) <- "logical" : 
    (list) object cannot be coerced to type 'double' 
Calls: sapply -> lapply -> FUN -> ifelse 

顯然我做的事錯了,但我不確定它是什麼。我查看了ifelse的幫助文件,但我不明白輸出的錯誤消息。我已經獲得了代碼以低效的方式運行,但是我真的很想獲得一些關於如何提高我未來編碼的反饋和知識。

謝謝!

回答

4

如果它對於data.frame中的所有變量都是相同的值(99),那麼就一次對整個data.frame進行操作。

> sum(data*(data < 99)) 
[1] -39.68282 

如果你想行總結

rowSums(data*(data < 99)) # faster than apply(data*(data < 99), 1, sum) 

如果你想列總結

colSums(data*(data < 99)) # faster than apply(data*(data < 99), 2, sum) 
+0

+1優秀的答案;)我不確定是否Tony想要總金額或行數。 – csgillespie 2011-04-01 20:04:13

+0

@csgillespie:我認爲你是對的;他想要這筆錢。 – 2011-04-01 20:11:11

+0

感謝您的幫助!我會研究這個。我遇到的一個問題是,我正在求和的這些值只是更大數據集的一部分。我認爲,如果沒有別的,這是一種簡化我的代碼的方法,將它們編碼爲更小的數據框架,並按照您的建議製作應用程序。再次感謝 – Tony 2011-04-01 20:48:58

4

如果我正確理解你的問題,我認爲,所有你需要做的是:

## Set any skip values to be equal to zero 
data[data == 99] = 0 
## Work out the row means 
apply(data, 1, sum) 

One commen噸。你考慮使用R的缺失值對象NA,而不是將99設置爲0.

+2

OP:請注意,如果你將'99'設置爲'NA',你需要'apply(data,1,sum,na.rm = TRUE)' – 2011-04-01 20:19:02