编辑:我稍微修改了一下这个问题。我抱怨一开始就没有理解问题的全部性质。
我正致力于清理从多个人那里收集的数据。虽然大多数人以正确的格式输入数据,但我发现其中一些是“懒惰的条目”'
以下是我的输入数据集:
| 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中这样做的任何想法?我知道这应该是可行的,我不知道在哪里寻找答案。
答案 0 :(得分:2)
我们可以使用cSplit
中的library(splitstackshape)
来分割' ID'在/
列,通过指定direction='long'
,我们会重新设置来自“{1}”的数据。长期'格式。输出是data.table
,因此我们可以使用标准data.table技术。我们按名称'分组,并创建另一个分组变量(' ind'),以便相邻的2个元素属于一个组。在下一步中,我们将按名称'分组。和' ind',根据nchar
和substr
获取max
' ID',min
第一个元素nchar
,paste
它与第二个元素(这是基于提供的示例。如果首先出现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))