【问题标题】:Is there a way to split columns in R with and impute implied Values有没有办法用隐含值拆分 R 中的列并估算隐含值
【发布时间】:2019-12-10 16:23:15
【问题描述】:

我正在尝试拆分数据集中的一列,其中代码由“-”分隔。这产生了两个问题。首先,我必须拆分列,但我也想估算“-”所暗示的值。我能够使用以下方法拆分数据:

separate_rows(df, code, sep = "-")

但我仍然没有找到估算隐含值的方法。

name <- c('group1', 'group1','group1','group2', 'group1', 'group1', 
'group1')
code <- c('93790', '98960 - 98962', '98966 - 98969', '99078', 'S5950', 
'99241 - 99245', '99247')
df <- data.frame( name, code)

我试图输出的内容类似于:

group1 93790, 98960, 98961, 98962, 98966, 98967, 98968, 98969, S5950, 99241, 
99242, 99243, 99244, 99245, 99247
group2 99078

在本例中,98961、98967 和 98968 是从“-”推算和暗示的。

关于如何实现这一点的任何想法?

【问题讨论】:

  • 98966-98969 正在更新中
  • 这是我第一行得到的group1 93790, 98960, 98961, 98962, 98966, 98967, 98968, 98969, S5950, 99241, 99242, 99243, 99244, 99245, 99247

标签: r dplyr tidyr


【解决方案1】:

在我们拆分“代码”后,一个选项是循环使用map 拆分元素,得到一个序列 (:)、unnest 并执行 group_by paste

library(dplyr)
library(stringr)
library(tidyr)
library(purrr)
df %>% 
  mutate(code = map(strsplit(as.character(code), " - "), ~  {
      x <- as.numeric(.x)
      if(length(x) > 1)  x[1]:x[2] else x})) %>%
  unnest(code) %>%
  group_by(name) %>%
  summarise(code = str_c(code, collapse=", "))
# A tibble: 2 x 2
#   name   code                                                  
#   <fct>  <chr>                                                  
# 1 group1 93790, 98960, 98961, 98962, 98966, 98967, 98968, 98969
# 2 group2 99078        

或者另一个选项是在separate_rows之前,创建一个行索引并在我们执行complete时使用它进行分组

df %>% 
    mutate(rn = row_number()) %>%
    separate_rows(code, convert = TRUE) %>% 
    group_by(rn, name) %>%
    complete(code = min(code):max(code)) %>%
    group_by(name) %>%
    summarise(code = str_c(code, collapse =", "))

更新

如果有非数字元素

df %>% 
 mutate(rn = row_number()) %>%
 separate_rows(code, convert = TRUE) %>%
 group_by(name, rn) %>% 
 complete(code = if(any(str_detect(code, '\\D'))) code else 
     as.character(min(as.numeric(code)):max(as.numeric(code)))) %>% 
 group_by(name) %>%
 summarise(code = str_c(code, collapse =", "))
# A tibble: 2 x 2
#  name   code                                                                                                   
#  <fct>  <chr>                                                                                                  
#1 group1 93790, 98960, 98961, 98962, 98966, 98967, 98968, 98969, S5950, 99241, 99242, 99243, 99244, 99245, 99247
#2 group2 99078                 

【讨论】:

  • 太美了!按预期工作。感谢您的快速帮助!
  • 当我将此代码应用于我的真实数据集时,会出现以下错误。知道可能是什么原因造成的吗?我没有看到任何缺失值有没有办法将 NA 作为异常处理? [ x[1]:x[2] 中的错误:NA/NaN 参数]
  • @Brad_J 你能用separate_rows 尝试第二种解决方案并检查它是否给出错误
  • 谢谢。我仍然收到 NA 错误。 [ min(code):max(code) 中的错误:NA/NaN 参数]
  • @Brad_J 也许你在'code'中有一些NA元素你能检查df %&gt;% mutate(rn = row_number()) %&gt;% separate_rows(code, convert = TRUE) %&gt;% group_by(rn, name) %&gt;% summarise(code = sum(is.na(code)))
【解决方案2】:
lapply(split(as.character(df$code), df$name), function(y) {
    unlist(sapply(y, function(x){
        if(grepl("-", x)) {
            n = as.numeric(unlist(strsplit(x, "-")))
            n[1]:n[2]
        } else {
            as.numeric(x)
        }
    }, USE.NAMES = FALSE))
})
#$group1
#[1] 93790 98960 98961 98962 98966 98967 98968 98969

#$group2
#[1] 99078

【讨论】:

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