【问题标题】:Replace first number character with sub and if in R用 sub 和 if 在 R 中替换第一个数字字符
【发布时间】:2020-04-24 10:36:42
【问题描述】:

我想将这 3 个以 5 开头的字符数字替换为 1。我尝试使用 sub if 条件,但它失败了

DO_concatenated:

    DTNASC   AGE
1   3031997  520
2   9022017  0
3   13071933 83
4   6022002  515
5   2061966  50
6   28121946 70
7   4121955  61
8   3101943  73
9   6022017  20
10  14012017 0
11  20071931 8

if((nchar(DO_concatenated$AGE) == 3)&(funcaoidade(DO_concatenated$AGE) == 5)){
  DO_concatenated$IDADE = sub(pattern = 5, replacement = 1, DO_concatenated$AGE) 
}

如果它有效,输出将是这样的:

    DTNASC   AGE
1   3031997  120
2   9022017  0
3   13071933 83
4   6022002  115
5   2061966  50
6   28121946 70
7   4121955  61
8   3101943  73
9   6022017  20
10  14012017 0
11  20071931 8

我之前这样做是为了删除以 4 开头的变量,代码如下:

if((nchar(DO_concatenated$IDADE) == 3)&(funcaoidade(DO_concatenated$IDADE) == 4)){
  DO_concatenated$IDADE = sub(pattern = 4, replacement = "", DO_concatenated$IDADE) 
}

它成功了!

"funcaoidade" 查找数字的第一个字符

funcaoidade = function(x){
  substr(x, start = 1, stop = 1)
}

那么,有什么区别? 提前致谢!

【问题讨论】:

  • 请按照您之前发布的解决方案i1 <- (nchar(DO_concatenated$AGE) == 3)&(funcaoidade(DO_concatenated$AGE) == 5); DO_concatenated$IDADE[i1] = sub(pattern = 5, replacement = 1, DO_concatenated$AGE[i1])的方式使用它
  • 谢谢,但您知道如何解释为什么第一个解决方案有效,然后不再有效吗?它与变量类有关吗?
  • if/else 的输出是单个 TRUE/FALSE,它期望作为输入单个 TRUE/FALSE。如果该输出值为单个 TRUE,则它将在整个列上执行 sub,如果为 FALSE,则不会
  • (nchar(DO_concatenated$AGE) == 3)&(funcaoidade(DO_concatenated$AGE) == 5) [1] TRUE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 现在,第一个值是TRUE,当您执行if/else 时,它需要第一个if((nchar(DO_concatenated$AGE) == 3)&(funcaoidade(DO_concatenated$AGE) == 5)) print("hello") [1] "hello"
  • 好的,我去看看!谢谢!

标签: r if-statement replace conditional-statements


【解决方案1】:

这是一种使用 stringr 包的方法;

library(dplyr)
library(stringr)

data <-
  data.frame(
    DTNASC = c(3031997, 9022017, 13071933, 6022002, 2061966, 28121946, 4121955, 
               3101943, 6022017, 14012017, 20071931),
    AGE = c(520, 0, 83, 515, 50, 70, 61, 73, 20, 0, 8)
  )

data %>%
  mutate(# Replacement of Age
    # To convert it into character to make it easier
    AGE = as.character(AGE),
    # Here 5 is the character we are checking in first character
    # str_sub(AGE, 1, 1) -> Checks first character
    # nchar(AGE) == 3 -> Checks if the length of AGE is 3
    # str_replace(AGE, "5", "1") -> Replaces 5 with 1
    # as.numeric() -> To convert to a number
    AGE = ifelse(str_sub(AGE, 1, 1) == "5" & nchar(AGE) == 3,
                 as.numeric(str_replace(AGE, "5", "1")),as.numeric(AGE)),

    # Replacement of DTNASC
    # To convert it into character to make it easier
    DTNASC = as.character(DTNASC),
    # Here 4 is the character we are checking in first character
    # str_sub(DTNASC, 1, 1) -> Checks first character
    # nchar(DTNASC) == 7 -> Checks if the length of DTNASC is 7
    # str_replace(DTNASC, "4", "") -> Replaces 4 with null
    # as.numeric() -> To convert to a number
    DTNASC = ifelse(str_sub(DTNASC, 1, 1) == "4" & nchar(DTNASC) == 7,
                 as.numeric(str_replace(DTNASC, "4", "")),as.numeric(DTNASC)))

# DTNASC AGE
# 3031997 120
# 9022017   0
# 13071933  83
# 6022002 115
# 2061966  50
# 28121946  70
# 121955  61
# 3101943  73
# 6022017  20
# 14012017   0
# 20071931   8

【讨论】:

    【解决方案2】:

    您可以使用正则表达式来执行此操作:

    df$AGE1 <- as.integer(sub("^5(..)", "1\\1", df$AGE))
    df
    
    #     DTNASC AGE AGE1
    #1   3031997 520  120
    #2   9022017   0    0
    #3  13071933  83   83
    #4   6022002 515  115
    #5   2061966  50   50
    #6  28121946  70   70
    #7   4121955  61   61
    #8   3101943  73   73
    #9   6022017  20   20
    #10 14012017   0    0
    #11 20071931   8    8
    

    这将替换以 5 到 1 开头的 3 位数字的第一个数字。创建了一个新列 AGE1 来比较输出。如果需要,可以覆盖AGE 列。

    数据

    df <- structure(list(DTNASC = c(3031997, 9022017, 13071933, 6022002, 
    2061966, 28121946, 4121955, 3101943, 6022017, 14012017, 20071931
    ), AGE = c(520, 0, 83, 515, 50, 70, 61, 73, 20, 0, 8)), class = "data.frame", 
    row.names = c(NA, -11L))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-05
      • 2023-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-14
      • 2020-03-10
      • 1970-01-01
      相关资源
      最近更新 更多