【发布时间】:2016-05-20 06:03:05
【问题描述】:
我有一个包含很多列的 data.table。我需要遍历它们并使用某些条件创建新列。目前我正在为每一列编写单独的条件行。让我用一个例子来解释。让我们将样本数据视为 -
set.seed(71)
DT <- data.table(town = rep(c('A','B'), each=10),
tc = rep(c('C','D'), 10),
one = rnorm(20,1,1),
two = rnorm(20,2,1),
three = rnorm(20,3,1),
four = rnorm(20,4,1),
five = rnorm(20,5,2),
six = rnorm(20,6,2),
seven = rnorm(20,7,2),
total = rnorm(20,28,3))
对于从 1 到总计的每一列,我需要创建 4 个新列,即 mean、sd、uplimit、lowlimit 用于 2 sigma 异常值计算。我正在这样做 -
DTnew <- DT[, as.list(unlist(lapply(.SD, function(x) list(mean = mean(x), sd = sd(x), uplimit = mean(x)+1.96*sd(x), lowlimit = mean(x)-1.96*sd(x))))), by = .(town,tc)]
然后我将把这个 DTnew data.table 与我的 DT 合并
DTmerge <- merge(DT, DTnew, by= c('town','tc'))
现在想出异常值,我正在为每个变量编写单独的代码集 -
DTAoutlier <- DTmerge[ ,one.Aoutlier := ifelse (one >= one.lowlimit & one <= one.uplimit,0,1)]
DTAoutlier <- DTmerge[ ,two.Aoutlier := ifelse (two >= two.lowlimit & two <= two.uplimit,0,1)]
DTAoutlier <- DTmerge[ ,three.Aoutlier := ifelse (three >= three.lowlimit & three <= three.uplimit,0,1)]
有人可以帮助简化这段代码,以便
我不必为异常值编写单独的代码行。在这个例子中,我们只有 8 个变量,但是如果我们有 100 个变量,我们最终会写 100 行代码吗?这可以使用 for 循环来完成吗?怎么样?
-
一般而言,对于 data.table,我们如何添加保留原始列的新列。例如,下面我记录第 3 到第 10 列。如果我不创建新的 DTlog,它会覆盖 DT 中的原始列。如何在 DT 中保留原始列并在 DT 中保留新列。
DTlog <- DT[,(lapply(.SD,log)),by = .(town,tc),.SDcols=3:10]
期待一些专家的建议。
【问题讨论】:
-
我知道您特别在寻找
data.table解决方案,但请注意您正在寻找的基本上是data.table相当于dplyr的 @ 可能会有所帮助987654329@ -
@shreyasgm 将其作为答案发布
-
@Prasad 这样做有什么意义?为什么你在一个组中一遍又一遍地写相同的 4 个数字?
标签: r data.table