R - 未正确输入的清洁号码

时间:2015-08-31 15:33:49

标签: r data-cleansing

编辑:我稍微修改了一下这个问题。我抱怨一开始就没有理解问题的全部性质。

我正致力于清理从多个人那里收集的数据。虽然大多数人以正确的格式输入数据,但我发现其中一些是“懒惰的条目”'

以下是我的输入数据集:

|  ID                       | Name    | Age  |
|--------------------------------------------|
|  123456/7/56617181/82     | ABC     | 23   |
|  12134/135                | CDE     | 24   |

这就是我想要的:

|  ID                               | Name    | Age  |
|----------------------------------------------------|
|  123456/123457/56617181/56617182  | ABC     | 23   |
|  12134/12135                      | CDE     | 24   |

有了这个,我需要做的就是为每个ID生成一个单独的行。我已经把这一点弄清楚了。尽管如此,这是我最终会有的:

|  ID         | Name    | Age  |
|------------------------------|
|  123456     | ABC     | 23   |
|  123457     | ABC     | 23   |
|  56617181   | ABC     | 23   |
|  56617182   | ABC     | 23   |
|  12134      | CDE     | 24   |
|  12135      | CDE     | 24   |

关于如何在R中这样做的任何想法?我知道这应该是可行的,我不知道在哪里寻找答案。

1 个答案:

答案 0 :(得分:2)

我们可以使用cSplit中的library(splitstackshape)来分割' ID'在/列,通过指定direction='long',我们会重新设置来自“{1}”的数据。长期'格式。输出是data.table,因此我们可以使用标准data.table技术。我们按名称'分组,并创建另一个分组变量(' ind'),以便相邻的2个元素属于一个组。在下一步中,我们将按名称'分组。和' ind',根据ncharsubstr获取max' ID',min第一个元素ncharpaste它与第二个元素(这是基于提供的示例。如果首先出现nchar较少的值,我们可能必须使用which.max来选择要在substr中使用的元素,连接(c)第一个元素,转换为numeric以创建' ID'列。

library(splitstackshape)
library(data.table)
cSplit(df1, 'ID', '/', 'long')[, ind:=gl(.N, 2, .N) , by = Name
       ][, {i1 <- nchar(ID)
            list(ID=as.numeric(c(ID[1],
              paste0(substr(ID[1],1, max(i1)-min(i1)), ID[2]))),
             Age=Age)} , by = .(Name, ind)][, ind:= NULL][]
#  Name       ID Age
#1:  ABC   123456  23
#2:  ABC   123457  23
#3:  ABC 56617181  23
#4:  ABC 56617182  23
#5:  CDE    12134  24
#6:  CDE    12135  24

正如我上面提到的,如果首先出现具有较短子字符串的ID值,我们可能必须使用which.max/which.min来选择&#39; ID&#39;

cSplit(df1, 'ID', '/', 'long')[, ind:=gl(.N, 2, .N) ,Name
       ][,{i1 <- nchar(ID)
          i2 <- which.max(i1)
          i3 <- which.min(i1)
          list(ID=c(ID[i2],paste0(substr(ID[i2], 1, max(i1)-min(i1)), 
                  ID[i3])), Age=Age)} ,
                               by = .(Name, ind)]

数据

df1 <- structure(list(ID = c("123456/7/56617181/82", "12134/135"),
 Name = c("ABC", 
"CDE"), Age = 23:24), .Names = c("ID", "Name", "Age"), 
class = "data.frame", row.names = c(NA, -2L))