繁体   English   中英

将功能应用于分组的数据帧

[英]Apply function to data frames grouped by

我想将一个函数应用于数据帧的子集,这些子集是在按变量分组后从初始帧开始的。 因此,我正在寻找与apply或类似方法等效的包装器, apply整个数据帧作为输入并输出矢量。 这是因为手边的函数需要来自不同位置的行和列的条目,并且不能简化为仅使用行和列,因此具有lapplyapply(df, 1(2),...)

让我们考虑以下示例:

iris   <- data.table(iris)

my.function <- function(sub.data){
v <- c(NA)
    for(j in 2:dim(sub.data)[1]){
        if(sub.data[j,1, with = FALSE] > sub.data[j-1,2, with = FALSE]+2){
            v[j] <- "ok"
        } else {
            v[j] <- "not ok"    
        }
    }
    return(v)
}

执行my.function(iris)可以正常工作,但是假设我只想将功能应用于具有相同Species的组。 因此,在data.table语法中,它应类似于:

results <- iris[,
                wrapper(.SD, my.function),
                by = Species
                ]

wrapper是我正在寻找的环境,类型为lapply或类似类型。 同样,也可以使用dplyr包,但我不知道相应的语法是什么:我已经尝试过

results <- iris %>%
                group_by(Species) %>%
                     summarise(results = my.function(iris))

但这似乎无法产生正确的结果,因为它仍然针对每个物种的整个数据集运行,而不是分成子集。

看来您这里不需要wrapper 只需在.SD上运行您的功能即可满足您的需求。

library(data.table)
#your function works with a data.table
#by below will create smaller data tables on which you can directly
#run my.function on
iris[, my.function(.SD), by=Species]

输出:

       Species     V1
  1:    setosa     NA
  2:    setosa not ok
  3:    setosa not ok
  4:    setosa not ok
  5:    setosa not ok
 ---                 
146: virginica     ok
147: virginica     ok
148: virginica     ok
149: virginica     ok
150: virginica     ok

目的是不使用软件包吗?

输出向量的长度是否与data.frame的行数相同? 如果是这样,请在我们使用测试my.function地方尝试ave ,该my.function返回行数乘以其输入数据帧的列数:

my.function <- function(x) prod(dim(x)) # test function
ave(1:nrow(iris), iris$Species, FUN = function(ix) my.function(iris[ix, ]))
##  [1] 250 250 250 250 250 250 250 250 ...

如果my.function返回的向量的长度与输入的行数相同,则上述方法也适用。

在这种情况下,如果只需要长度为3的向量:

tapply(1:nrow(iris), iris$Species, function(ix) my.function(iris[ix, ]))
## setosa versicolor  virginica 
##    250        250        250 

by

c(by(iris, iris$Species, my.function))
## setosa versicolor  virginica 
##    250        250        250 

sapply/split

sapply(split(iris, iris$Species), my.function)
## setosa versicolor  virginica 
##    250        250        250 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM