簡體   English   中英

從數據框中刪除某些行的功能

[英]Function to remove certain rows from dataframe

我正在嘗試編寫一個從數據框中刪除某些行的函數。 為簡單起見,讓我們假設要刪除的條件是該行中至少有一個NA。

    df = data.frame(c("A","B","C"),c(1,NA,3))
fn = function (d) {

  for (x in 1:nrow(d)) { for (y in 1:ncol(d)) {
if(is.na(d[x,y])) d = d[-x,] 
 }}}

fn(df)

PS:我知道有更好的方法來刪除行號至少為1的NA,即df = df [-which(!complete.cases(df)],但我很想知道為什么我編寫的代碼不起作用。

您需要從函數中顯式返回d

df <- data.frame(X1 = c("A","B","C"), X2 = c(1,NA,3))
fn <- function (d) {
  for (x in 1:nrow(d)) {
    for (y in 1:ncol(d)) {
      if(is.na(d[x,y])) d = d[-x,] 
    }
  }
d # return d
}

fn(df)

> fn(df)
  X1 X2
1  A  1
3  C  3

R隱式返回最后一個操作的結果,但這是對第三行的if (...)進行評估的結果,該行返回NULL

> foo <- fn(df) # using your fn()
> foo
NULL

您可以在函數末尾顯式調用return(d) ,但是由於R還在最后一條語句上調用return() ,就像調用return(return(d)) 結果,您可以僅在函數的最后一行使用d ,而R做正確的事情。

不使用return()的主要例外(即何時應使用它)是在您可能想從函數中盡早返回的情況下。

最后,不要只遍歷對象的行和列,而要考慮按行工作。 R是向量化的,因此您可以在整行上執行is.na() (例如),然后if()語句將是if (any(is.na(d[i, ])) ,其中i是循環索引,例如:

fn2 <- function (d) {
  for (i in 1:nrow(d)) {
    if (any(is.na(d[i,]))) {
      d <- d[-i, ]
    }
  }
d # return d
}

> fn2(df)
  X1 X2
1  A  1
3  C  3

甚至有更有效的方法來執行此操作,但是如果您以向量化的方式思考,您將開始編寫更簡單,更快速的R代碼。

函數式編程風格

我認為OP缺少的是您不能直接修改作為參數傳遞的變量。 那是函數式編程風格。

訪問https://en.wikipedia.org/wiki/Functional_programming

實際上,函數主體中的變量是作為參數傳遞的變量的副本。 因此,您正在處理副本。

這就是為什么您必須返回副本並將其重新分配給變量的原因。

df <- data.frame(X1 = c("A","B","C"), X2 = c(1,NA,3))
fn <- function (d) {
        for (x in 1:nrow(d)) {
          for (y in 1:ncol(d)) {
            if(is.na(d[x,y])) d = d[-x,]}}
         d} # return d

df <- fn(df)

df現在如OP所願

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM