【问题标题】:Basic Function to remove 0 values from a df based on a specific column基于特定列从df中删除0值的基本功能
【发布时间】:2021-12-25 01:31:33
【问题描述】:

我正在尝试创建一个非常基本的函数,我想根据 df 中的特定列从 df 中删除任何 0 值(或更少)。当我在函数之外运行这些行时,它们可以工作,但是当我尝试在函数中运行它们时,出现此错误“$<-.data.frame(*tmp*, name, value = numeric(0)) 中的错误:替换有 0 行”。有谁知道问题出在哪里?

Remove_Missing=function(x,name){
  x$name=as.numeric(x$name)
  x=x[x$name>0,]
}

编辑:
示例代码:

#First two lines work but those same two lines won't work if function is called
merged_data$name=as.numeric(merged_data$HETENURE)
merged_data=merged_data[merged_data$HETENURE>0,]
Remove_Missing(merged_data, HETENURE) #Call function

数据

structure(list(HRHHID = c("008906910993941", "008906910993941", 
"648061954059610", "160916068405549", "160916068405549", "168069009100998"
), HRYEAR4 = c("2010", "2010", "2010", "2010", "2010", "2010"
), HETENURE = c(" 1", " 1", " 3", " 1", " 1", " 1"), HEFAMINC = c("11", 
"11", "10", "13", "13", "14"), HRNUMHOU = c(" 2", " 2", " 1", 
" 2", " 2", " 3"), GESTFIPS = c("01", "01", "01", "01", "01", 
"01"), GTMETSTA = c("2", "2", "1", "1", "1", "1"), PEMARITL = c(" 1", 
" 1", " 4", " 1", " 1", " 1"), PESEX = c(" 2", " 1", " 1", " 2", 
" 1", " 2"), PEEDUCA = c("40", "45", "40", "42", "41", "39"), 
    PTDTRACE = c(" 1", " 1", " 1", " 1", " 1", " 1"), PEHSPNON = c(" 2", 
    " 2", " 2", " 2", " 2", " 2"), PEMLR = c(" 5", " 5", " 5", 
    " 1", " 1", " 7"), PRFTLF = c("-1", "-1", "-1", " 1", " 1", 
    "-1"), PRHRUSL = c("-1", "-1", "-1", " 4", " 4", "-1"), HESP1 = c("-1", 
    "-1", "-1", "-1", "-1", "-1"), HESP6 = c("-1", "-1", "-1", 
    "-1", "-1", "-1"), HESP7A = c("-1", "-1", "-1", "-1", "-1", 
    "-1"), HESP8 = c("-1", "-1", "-1", "-1", "-1", "-1"), HRFS12M1 = c(" 1", " 1", " 1", " 1", " 1", " 1")), row.names = c(9L, 10L, 11L, 
12L, 13L, 15L), class = "data.frame")

【问题讨论】:

  • 请显示数据、有效的代码和“无效”的代码,以及所谓的不当输出
  • 请注意,当人们要求澄清时,我们通常应该编辑问题以反映这一点。请避免使用 cmets 部分进行重要编辑,但要编辑问题
  • 我们可以随时通过粘贴dput(merged_data)dput(head(merged_data))的输出来共享数据
  • 函数没有返回值。在最后一行代码中删除 x= 部分,仅保留 x[x$name>0,] 并查看它提供了什么。
  • 同样的错误,但我试过了。更新了上面的问题。

标签: r function


【解决方案1】:

这里有两个问题和一个启用错误:

  1. 您使用function(x, name) 定义您的函数,然后尝试将特定列引用为x$name,这应该会失败。也就是说,如果name 应该识别(通过标准评估)一列,那么它实际上应该是一个字符串,而$ 不能那样工作。您应该改用x[[name]](请参阅The difference between bracket [ ] and double bracket [[ ]] for accessing the elements of a list or dataframe)。

    这并不是一个问题(尽管它应该),但是,因为接下来的两个错误。

  2. 你正在调用你的函数

    Remove_Missing(merged_data, HETENURE)
    

    但由于您没有尝试进行非标准评估 (NSE),因此使用 HETENURE 是错误的。应该发生的是,在你的函数中,当它的 name 被引用时,它应该寻找一个名为 HETENURE 的对象而不是找到它; Error: object 'HETENURE' not found 应该会出错。我认为你应该做的是

    Remove_Missing(merged_data, "HETENURE")
    
  3. 与其说是一个漏洞,不如说是一个让其他漏洞未被发现的弱点:你分配了merged_data$name <- as.numeric(...),所以在你的函数中x$name应该引用x$HETENURE应该失败,而是在您的数据中找到一个名为 name 的列(因此从未引用/使用函数传递的 name 参数)。

首先,让我们删除名为name的列的诱人隐藏错误:

merged_data$name <- NULL

二、固定功能:

Remove_Missing = function(x, name) {
  x[[name]] = as.numeric(x[[name]])
  x[x[[name]] > 0,]
}

三、修复调用并获取返回数据:

Remove_Missing(merged_data, "HETENURE")
#             HRHHID HRYEAR4 HETENURE HEFAMINC HRNUMHOU GESTFIPS GTMETSTA PEMARITL PESEX PEEDUCA PTDTRACE PEHSPNON PEMLR PRFTLF PRHRUSL HESP1 HESP6 HESP7A HESP8 HRFS12M1 name
# 9  008906910993941    2010        1       11        2       01        2        1     2      40        1        2     5     -1      -1    -1    -1     -1    -1        1    1
# 10 008906910993941    2010        1       11        2       01        2        1     1      45        1        2     5     -1      -1    -1    -1     -1    -1        1    1
# 11 648061954059610    2010        3       10        1       01        1        4     1      40        1        2     5     -1      -1    -1    -1     -1    -1        1    3
# 12 160916068405549    2010        1       13        2       01        1        1     2      42        1        2     1      1       4    -1    -1     -1    -1        1    1
# 13 160916068405549    2010        1       13        2       01        1        1     1      41        1        2     1      1       4    -1    -1     -1    -1        1    1
# 15 168069009100998    2010        1       14        3       01        1        1     2      39        1        2     7     -1      -1    -1    -1     -1    -1        1    1

当然,在这种情况下,没有任何内容被过滤掉(因为您的所有数据都通过了条件),所以如果我暂时修改函数以设置&gt; 1 为条件,我们会看到变化:

Remove_Missing = function(x, name) {
  x[[name]] = as.numeric(x[[name]])
  x[x[[name]] > 1,]
}
Remove_Missing(merged_data, "HETENURE")
#             HRHHID HRYEAR4 HETENURE HEFAMINC HRNUMHOU GESTFIPS GTMETSTA PEMARITL PESEX PEEDUCA PTDTRACE PEHSPNON PEMLR PRFTLF PRHRUSL HESP1 HESP6 HESP7A HESP8 HRFS12M1 name
# 11 648061954059610    2010        3       10        1       01        1        4     1      40        1        2     5     -1      -1    -1    -1     -1    -1        1    3

【讨论】:

  • 非常感谢您花时间给出解释!
  • 希望对您有所帮助,托尼​​。 既然你是新人...如果你的问题得到解决,请accept回答。不用着急,获得更多关注和可能不同的答案的常用策略是让它在一段时间内不被接受(几天?)。但请记住在某个时候回来接受。 (如果有多个答案,您只能接受一个,但一旦您获得更多代表,您就可以根据需要投票。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-10
  • 1970-01-01
  • 1970-01-01
  • 2014-07-18
  • 2014-12-03
  • 2017-05-19
相关资源
最近更新 更多