簡體   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