【问题标题】:R: Write function that finds 0 and replaces it with certain valueR:写函数找到0并将其替换为某个值
【发布时间】:2018-09-02 23:51:01
【问题描述】:

我正在尝试编写一个函数来查找一个变量中的零并将这些零替换为除法的结果,包括另一个变量的值。

我的数据:

id apr_days apr_hours    
A      1       7 
B      2       14 
C      0       8 
D      0       15
E      0        0

我试图记录一个人使用某项策略的时间量。在 apr_hours > 0 的所有情况下,apr_days 中都需要有一个条目来指示相应的天数(apr_hours /7 的值,向下舍入以仅显示偶数)。

预期输出:

id apr_days apr_hours    
A      1       7 
B      2       14 
C      1       8 
D      2       15
E      0       0

我想告诉 R 的是:对于所有具有 apr_hours >0 & apr_days ==0 的观察值,取 apr_hours 的相应值,除以 7;向下舍入到偶数计数值并将apr_days 中的0 替换为此值。

我认为函数的结构应该是这样的:

if apr_hours == 0 {   
    if true: do nothing     
    } else {    
   check whether apr >0   
   if true: do nothing    
   } else {     
   calculate apr_hours/7,
   round down to even counts,
   and replace the 0 of apr_days with this result
   }

我完全迷失了,不知道如何准确地编写代码。任何帮助将不胜感激。

【问题讨论】:

    标签: r function replace


    【解决方案1】:
    if (apr_hours[i] == 0) apr_hours[i] = Math.Floor(apr_days[i]/2)
    

    这是你要找的吗?

    【讨论】:

    • 我马上试试。问题是,在正常情况下, apr_days 应该已经被填满了。因此,我只是试图解决默认情况下未填充 apr_days 的那些错误。而且我不确定您的功能是否这样做;在我看来,它只是覆盖了所有 apr_days 观察 - 我就在这里吗?
    • 附注:Math.Floor 是做什么的?
    • 它是 javascript :)。使用floor
    • R 无法识别 i - 我应该在那里填写什么?
    【解决方案2】:
    a <- matrix(c(1, 7, 2, 14, 0, 8, 0, 15, 0, 0), 5, 2, byrow = T)
    a[, 1] <- replace(a[, 1], which(a[, 1] == 0), floor(a[a[, 1] == 0,  2]/7))
    

    【讨论】:

      【解决方案3】:

      你去吧:

      within(df1,apr_days[apr_days==0] <- apr_hours[apr_days==0] %/% 7)
      #   id apr_days apr_hours
      # 1  A        1         7
      # 2  B        2        14
      # 3  C        1         8
      # 4  D        2        15
      # 5  E        0         0
      

      这是一个遵循(并纠正)您的逻辑的解决方案:

      df1$apr_days <-
        ifelse(df1$apr_days == 0 & df1$apr_hours > 0,
               df1$apr_hours %/% 7,
               df1$apr_days)
      

      或者全部重新计算:

      df1$apr_days = df1$apr_hours %/% 7
      

      【讨论】:

      • 完美,谢谢!两个版本都解决了,虽然我更喜欢第二个版本,因为它直接用新值覆盖旧值。但是,有一个问题:它似乎只适用于大于 7 的值;在以下几个小时(4;6;等),它仍然给我一个 0;我也想在这里有 1 天。你知道该怎么做吗?
      • 你希望它向下取整,所以 6/7 == 0.857... 将被四舍五入为 0。使用 ceiling(x/7) 向上取整,或 round(x/7) 用于常规四舍五入
      【解决方案4】:

      使用data.table 并使用整数除法%/% 您可以:

      setDT(df)
      df[apr_days == 0, apr_days := apr_hours %/% 7]
      
      print(df)
      
          id apr_days apr_hours
      1:  A        1         7
      2:  B        2        14
      3:  C        1         8
      4:  D        2        15
      5:  E        0         0
      

      【讨论】:

        【解决方案5】:

        使用ifelse as 可以实现一个简单的解决方案:

        df$apr_days = ifelse(df$apr_days == 0 & df$apr_hours > 0 , 
                         floor(df$apr_hours/7), df$apr_days)
        df
        #    id apr_days apr_hours
        # 1  A        1         7
        # 2  B        2        14
        # 3  C        1         8
        # 4  D        2        15
        # 5  E        0         0
        

        【讨论】:

        • 谢谢,成功了!我面临与上述答案相同的问题,即小时 > 7 不会导致在 apr_days 中输入“1”。我正在尝试使用新命令解决此问题:df$apr_days = ifelse(df1$apr_days == 0 & df$apr_hours
        • @Hanna 很好用。我想你的意思是hours &lt; 7。如果是这样,您可以尝试嵌套ifelse: as df$apr_days = ifelse(df$apr_days == 0 &amp; df$apr_hours &lt; 7, 1, ifelse(df$apr_days == 0 &amp; df$apr_hours &gt; 0 , floor(df$apr_hours/7), df$apr_days))
        • 非常感谢您,您(以及在这里提供帮助的其他所有人)是我个人的英雄!成功了,哇!
        • @Hanna 乐于助人。您可以通过点击答案框左侧的tick 来接受答案。
        猜你喜欢
        • 2021-06-29
        • 2023-01-19
        • 2017-10-14
        • 2021-10-13
        • 1970-01-01
        • 1970-01-01
        • 2021-06-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多