2011-04-01 63 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