将函数应用于 data.table [R] 中具有条件的每一列

bos*_*hek 7 r data.table

我想对一列应用几个函数,但我想应用一些关于何时执行此操作的逻辑,在这种情况下,当另一列有一些 NA 时。为了说明,我将向iris数据集添加一些 NA并将其转换为 data.table:

library(data.table)

irisdt <- iris
## Prep some example data
irisdt[irisdt$Sepal.Length < 5,]$Sepal.Length <- NA
irisdt[irisdt$Sepal.Width < 3,]$Sepal.Width <- NA

## Turn this into a data.table
irisdt <- as.data.table(iris)
Run Code Online (Sandbox Code Playgroud)

如果我想申请max多个列,我会这样:

## Apply a function to individual columns
irisdt[, lapply(.SD, max), .SDcols = c("Petal.Length", "Petal.Width")]
#>    Petal.Length Petal.Width
#> 1:          6.9         2.5
Run Code Online (Sandbox Code Playgroud)

然而,在这种情况下,我想取出任何不是 NA 的行,Sepal.Length然后返回 max 和 min 以及我为 NA 子集的列的名称。下面是一种丑陋的实现方式,但希望能说明我所追求的:

## Here is what the table would look like
desired_table <- rbind(
  irisdt[!is.na(Sepal.Length), .(max = max(Petal.Length), min = min(Petal.Length), var = "Sepal.Length")],
  irisdt[!is.na(Sepal.Width), .(max = max(Petal.Length), min = min(Petal.Length), var = "Sepal.Width")]
)

desired_table
#>    max min          var
#> 1: 6.9 1.2 Sepal.Length
#> 2: 6.7 1.0  Sepal.Width
Run Code Online (Sandbox Code Playgroud)

reprex 包(v0.3.0)于 2020 年 1 月 14 日创建

关于我如何实现这一点的任何想法?

akr*_*run 7

melt如果我们按多列进行比较,可能是更好的选择。重塑成“长”格式,然后利用i与条件!is.na(value),而通过“可变”分组,并获得minmax指定变量

library(data.table)
melt(irisdt,  measure = c('Sepal.Length', 'Sepal.Width'))[!is.na(value),
   .(max = max(Petal.Length), min = min(Petal.Length)), .(variable)]
Run Code Online (Sandbox Code Playgroud)

如果我们对多个变量执行此操作,则使用 lapply(.SD, ...

  • 这很棒。这甚至可能更简洁: `melt(irisdt,measure = c('Sepal.Length', 'Sepal.Width'), na.rm = TRUE)[,.(max = max(Petal.Length), min =分钟(花瓣长度)),.(变量)]` (2认同)