2

我正在尝试做一些前后比较,下面是一个小样本:

dataset =
data.table(
Key1 = c("p","q","r"),
Key2 = c("a","b","c"),
a_pre = c(3,2,6),
b_pre = c(2,6,3),
a_post = c(1,2,3),
b_post = c(1,4,2)
#etc.
)

dataset[,a_compare := a_pre/a_post]
dataset[,b_compare := b_pre/b_post]
#etc.

问题是我拥有的数量不仅仅是 a 和 b,而且有时是可变的,因此手动编码每个比较不是一种选择。我试图避免eval(parse())

假设我有数量的名称c("a","b", etc.)。我目前的思考过程是这样的:

loop through the quantity names
{
grep on colnames(dataset) for each quantity name, 
use above to subset the pre and post column. include the keys in this subset.
send this subsetted dataset to a function that calculates pre/post irrespective of the specific quantity
merge result of function back to original dataset
}

我觉得必须有更好的方法来做到这一点。有任何想法吗?

4

3 回答 3

2

这是非常标准的使用get,而不是eval(parse在这里:

v = c("a", "b")
dataset[, paste0(v, "_compare") :=
            lapply(v, function(x) get(paste0(x, "_pre")) / get(paste0(x, "_post")))]
于 2013-09-26T16:11:32.987 回答
2

我发现一个for循环更容易编写和阅读:

basevars = c("a","b","c","d")
for (i in basevars)
    DT[, paste0(i,"_compare"):=get(paste0(i,"_pre"))/get(paste0(i,"_post"))]

我从来不知道为什么 R 不能只定义+处理字符串。目前这是一个错误,所以它不像它被使用或任何东西:

> "a"+"b"
Error in "a" + "b" : non-numeric argument to binary operator

否则你可以简单地做:

for (i in basevars)
    DT[, i+"_compare" := get(i+"_pre")/get(i+"_post")]
于 2013-09-26T17:31:20.630 回答
0

怎么样的东西

foo <- dataset[,grep("_pre", names(dataset))] / dataset[,grep("_post", names(dataset))]
names(foo) <- sub("pre", "comp", names(foo))

(我将您的 data.table 重新格式化为 data.frame。 - 尽管我确信它们非常有用,但我不知道 data.tables。)

于 2013-09-26T15:49:06.907 回答