【问题标题】:How can I convert a non-numeric variable column into two numeric variable columns?如何将非数值变量列转换为两个数值变量列?
【发布时间】:2020-10-06 09:16:48
【问题描述】:

使用 R,我需要帮助将一个非数字列转换为两个数字列。我想拆分 x 列中的非数字数据,破折号之前的值进入一列(开始),破折号之后的值进入另一列(结束)。然后,我想创建一个新的数字列,其中包含 Start 和 End 列之间的差异,差异中添加了 1。 (Diff 列包含年份计数,因此从 2011 年到 2018 年将是 8 年。)

我尝试这样做时遇到了意想不到的问题。首先,x 变量显示为一个因子。其次,开始和结束列中的数据不是数字,当我尝试将它们设为数字以便可以进行 Diff 计算时,我得到了一个强制错误。第三,我无法让 strsplit 工作。

我检查了 stackoverflow 解决方案是否存在类似问题,但无法找到一个对我有用的解决方案。

输入数据只是实际文件中的一小部分样本

我更喜欢使用 dplyr 的解决方案,但对其他解决方案持开放态度。

输入

dput(df)
structure(list(x = c(NA, "1950-1960", "1975-1986", "2011-2018"
)), class = "data.frame", row.names = c(NA, -4L))

输出

x          Start  End   Diff
1950-1960  1950   1960  11
1975-1986  1975   1986  12
2011-2018  2011   2018   8

【问题讨论】:

标签: r string dplyr split


【解决方案1】:
df$Start = as.numeric(unlist(lapply(strsplit(df$x, "-"), `[`, 1)))
df$End   = as.numeric(unlist(lapply(strsplit(df$x, "-"), `[`, 2)))
df$Diff  = df$End - df$Start + 1
df
          x Start  End Diff
1      <NA>    NA   NA   NA
2 1950-1960  1950 1960   11
3 1975-1986  1975 1986   12
4 2011-2018  2011 2018    8

【讨论】:

    【解决方案2】:

    G5W 非常适合基础 R,这是一个“tidyverse”版本:

    library(dplyr)
    library(tidyr) # separate
    df %>%
      filter(!is.na(x)) %>%
      tidyr::separate(x, into = c("Start", "End"), sep = "-", remove = FALSE, convert = TRUE) %>%
      mutate(Diff = End - Start + 1L)
    #           x Start  End Diff
    # 1 1950-1960  1950 1960   11
    # 2 1975-1986  1975 1986   12
    # 3 2011-2018  2011 2018    8
    

    【讨论】:

      【解决方案3】:

      一个快速但不灵活的解决方案是使用substr()按位置获取年份:

      df$Start <- as.numeric(substr(df$x, 1, 4))
      df$End <- as.numeric(substr(df$x, 6, 10))
      df$Diff <- df$End - df$Start + 1
      
      df[!is.na(df$Diff), ]
                x Start  End Diff
      2 1950-1960  1950 1960   11
      3 1975-1986  1975 1986   12
      4 2011-2018  2011 2018    8
      

      【讨论】:

        【解决方案4】:

        又一个 baseR 解决方案:

        df1[, c("Start", "End")] <- do.call(rbind, strsplit(df1$x, "-"))
        df1 <- transform(type.convert(df1), Diff = End - Start + 1)
        

        结果

        df1
        #          x Start  End Diff
        #1      <NA>    NA   NA   NA
        #2 1950-1960  1950 1960   11
        #3 1975-1986  1975 1986   12
        #4 2011-2018  2011 2018    8
        

        数据

        df1 <- structure(list(x = c(NA, "1950-1960", "1975-1986", "2011-2018"
        )), class = "data.frame", row.names = c(NA, -4L))
        

        【讨论】:

          【解决方案5】:

          基础 R,易于阅读

          #your data
          x <- c("1950-1960", "1975-1986", "2011-2018")
          df <- as.data.frame(x)
          
          #code
          df_list <- unlist(apply(df, MARGIN = 1, strsplit, "-"))
          new_data <- matrix(df_list, ncol = 2,byrow = T)
          
          #output
          output <- cbind(df,new_data)
          

          输出:

                    x    1    2
          1 1950-1960 1950 1960
          2 1975-1986 1975 1986
          3 2011-2018 2011 2018
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-08-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多