【问题标题】:Calculating difference with only natural numbers in R在R中仅计算自然数的差异
【发布时间】:2021-07-03 13:41:27
【问题描述】:

我想根据 2 年的差异对我的数据进行分类。
我想使用 diff 函数,但它不适用于负数。

我收到此错误

'lag' and 'differences' must be integers >= 1
df$new_var <- fcase(
  df$year1== df$year2, '4',
  diff(df$year1, df$year2) <= 5, '3',  
  diff(df$ipodate1, df$ipodate2) <= 10, '2',
  default = '0'
)

有什么方法可以计算绝对值的差异

df <- data.frame(
  year1 = c('1997','2008','2004','2010','2005','2007','2008'),
  year2 = c('1997','2018','1988','1929','2023','2012','2009'))

所以结局应该是这样的:

year1 year2 new_var
1997 1997 4
2008 20018 2
2004 1988 0

...

【问题讨论】:

  • 1. year 应该是数字类型 2。在 diff(df$year1, df$year2) &lt;= 5 中,LHS 是向量,RHS 只是单个 5
  • 检查 ?diff,你必须检查参数
  • 我使用了 ?diff 但我没有找到解决方案。我不擅长编程,不知道你的意思。在我的数据中,年份是数字
  • 您的年份列是因子,因此首先将它们转换为整数。然后只需使用 col3 = year1 - year2 或 cols3 = abs(year1- year2)。所以你可以在 col3 上使用 fcase。分两步做会更容易

标签: r


【解决方案1】:

这里我先把df变成数字类型。那么我更喜欢在data.table方法中使用fcase,如下所示

library(data.table)
df <- data.frame(
  year1 = c('1997','2008','2004','2010','2005','2007','2008'),
  year2 = c('1997','2018','1988','1929','2023','2012','2009')
)

% to numeric type
df2 <- data.frame(apply(df,2, FUN=function(x) as.numeric(x)))

setDT(df2)[,newvar:=fcase(year1 == year2,4,
                          abs(year1 - year2) <= 5, 3,
                          abs(year1 - year2) <= 10, 2,
                          default = 0)]
#   year1 year2 newvar
#1:  1997  1997      4
#2:  2008  2018      2
#3:  2004  1988      0
#4:  2010  1929      0
#5:  2005  2023      0
#6:  2007  2012      3
#7:  2008  2009      3

【讨论】:

  • 第二行应该是 2 ?还是不行?
  • 应该是2。
【解决方案2】:

这是使用case_whenabsdplyr 方式:

library(dplyr)
df %>%  
  type.convert(as.is = TRUE) %>% 
  mutate(new_var = case_when(year1 == year2 ~ 4,
                             abs(year1-year2) <=5 ~3,
                             abs(year1-year2) <=10 ~2,
                             TRUE ~ 0))

输出:

  year1 year2 new_var
1  1997  1997       4
2  2008  2018       2
3  2004  1988       0
4  2010  1929       0
5  2005  2023       0
6  2007  2012       3
7  2008  2009       3

【讨论】:

    【解决方案3】:

    您可以使用cut 传递中断和标签。

    df <- type.convert(df, as.is = TRUE)
    df$new_var <- cut(abs(df$year1 - df$year2),c(-Inf, 0, 5, 10, Inf), c(4, 3, 2, 0))
    df
    
    #  year1 year2 new_var
    #1  1997  1997       4
    #2  2008  2018       2
    #3  2004  1988       0
    #4  2010  1929       0
    #5  2005  2023       0
    #6  2007  2012       3
    #7  2008  2009       3
    

    【讨论】:

      【解决方案4】:

      我们也可以使用findInterval,效率更高

      df$new_var <- c(4, 3, 2, 0)[findInterval(abs(Reduce(`-`, type.convert(df, 
          as.is = TRUE))), c(-Inf, 0, 5, 10, Inf), left.open = TRUE)]
      df$new_var
      [1] 4 2 0 0 0 3 3
      

      【讨论】:

        猜你喜欢
        • 2018-07-21
        • 1970-01-01
        • 2014-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-29
        • 1970-01-01
        • 2022-01-17
        相关资源
        最近更新 更多