遍历data.table并根据某些条件创建新列

用户名

我有一个有很多列的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))

对于从一列到总数的每一列,我需要创建4个新列,即用于2 sigma离群值计算的均值,sd,上限,下限。我正在这样做-

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)]

可以帮助简化这段代码,以便

  1. 我不必为异常值编写单独的代码行。在此示例中,我们只有8个变量,但是如果我们有100个变量,最终会写100行代码吗?可以使用for循环来完成此操作吗?如何?

  2. 通常,对于data.table,我们如何添加保留原始列的新列。因此,例如在下面的示例中,我记录第3到10列的日志。如果不创建新的DTlog,它将覆盖DT中的原始列。如何在DT中保留原始列并在DT中保留新列。

    DTlog <- DT[,(lapply(.SD,log)),by = .(town,tc),.SDcols=3:10]

期待一些专家的建议。

阿克伦

我们可以使用来做到这一点:=我们对不是分组变量('nm')的列名进行子集化。vector使用outer('nm1')创建名称以分配给新列然后,我们使用OP的代码,unlist输出并将其分配(:=)到'nm1'以创建新列。

nm <- names(DT)[-(1:2)]

nm1 <- c(t(outer(c("Mean", "SD", "uplimit", "lowlimit"), nm, paste, sep="_")))

DT[, (nm1):= unlist(lapply(.SD, function(x) { Mean = mean(x)
                                  SD = sd(x)
                     uplimit = Mean + 1.96*SD
                     lowlimit = Mean - 1.96*SD
             list(Mean, SD, uplimit, lowlimit) }), recursive=FALSE) ,
                    .(town, tc)]

问题的第二部分涉及在列之间进行逻辑比较。一种选择是分别对初始列,“ lowlimit”和“ uplimit”列进行子集并进行比较(因为它们具有相同的维),以获得可以用强制转换为二进制的逻辑输出+然后将其分配给原始数据集以创建异常值列。

m1 <- +(DT[, nm, with = FALSE] >= DT[, paste("lowlimit", nm, sep="_"), 
          with = FALSE] & DT[, nm, with = FALSE] <= DT[, 
            paste("uplimit", nm, sep="_"), with = FALSE])
DT[,paste(nm, "Aoutlier", sep=".") := as.data.frame(m1)]

或者,除了比较data.tables之外,我们还可以使用for循环set(这样会更有效)

nm2 <- paste(nm, "Aoutlier", sep=".")
DT[, (nm2) := NA_integer_]
for(j in nm){
 set(DT, i = NULL, j = paste(j, "Aoutlier", sep="."), 
   value = as.integer(DT[[j]] >= DT[[paste("lowlimit", j, sep="_")]] & 
           DT[[j]] <= DT[[paste("uplimit", j, sep="_")]]))
 }

“日志”列也可以使用 :=

DT[,paste(nm, "log", sep=".") := lapply(.SD,log),by = .(town,tc),.SDcols=nm]

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用data.table,不创建新列的条件计算

来自分类Dev

循环遍历data.frame中的列,并根据循环中的计算创建一个新的data.frame

来自分类Dev

根据条件遍历熊猫列

来自分类Dev

带条件循环遍历data.table行

来自分类Dev

带条件循环遍历data.table行

来自分类Dev

循环遍历 data.frame 的列以应用条件

来自分类Dev

使用垂直条件和data.table创建一个新列

来自分类Dev

大熊猫遍历行和列,并根据某些条件进行打印

来自分类Dev

循环遍历data.table R中的列

来自分类Dev

在data.table中创建新列

来自分类Dev

遍历带条件的数组以创建新数组

来自分类Dev

R遍历数据框的各列以根据开始结束年份创建新列

来自分类Dev

R遍历数据框的各列以根据开始结束年份创建新列

来自分类Dev

遍历pandas列并创建新列

来自分类Dev

在创建新的列Matlab时遍历列

来自分类Dev

根据条件(按行)删除data.table中的列

来自分类Dev

根据条件(按行)删除data.table中的列

来自分类Dev

data.table根据变量分配新列

来自分类Dev

如何遍历data.frame的列并使用函数

来自分类Dev

遍历data.frame中的列以计算其值

来自分类Dev

在R中,逐行遍历data.frame并访问列值

来自分类Dev

根据列在data.table中创建序列

来自分类Dev

根据data.table中的计数创建列

来自分类Dev

用熊猫遍历df以创建新列

来自分类Dev

通过遍历字典列表并基于熊猫中的特定日期条件来创建新列

来自分类Dev

R:根据条件根据行值在data.frame中填充新列?

来自分类Dev

在for循环data.table中创建新列

来自分类Dev

在data.table中:遍历另一个data.table的行

来自分类Dev

如何依次遍历r data.frame中的每一行,然后遍历每一列?

Related 相关文章

热门标签

归档