R-未正确输入的清洁编号
编辑:我对问题做了一些修改。我为一开始没有理解问题的全部性质而道歉。 我正在清理从几个人那里收集的数据。虽然大多数人以正确的格式输入数据,但我发现其中一些是“惰性条目” 以下是我的输入数据集:R-未正确输入的清洁编号,r,data-cleaning,R,Data Cleaning,编辑:我对问题做了一些修改。我为一开始没有理解问题的全部性质而道歉。 我正在清理从几个人那里收集的数据。虽然大多数人以正确的格式输入数据,但我发现其中一些是“惰性条目” 以下是我的输入数据集: | ID | Name | Age | |--------------------------------------------| | 123456/7/56617181/82 | ABC | 23 | | 12134/135
| 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生成一个单独的行。尽管如此,这是我最终将拥有的:
你知道怎样才能在R里这样做吗?我知道这应该是可以做到的,我不知道在哪里寻找答案。我们可以使用
库中的cSplit
(splitstackshape)
来拆分/
处的“ID”列,通过指定方向class='long'
,我们将数据从“宽”格式重新格式化为“长”格式。输出是一个data.table
,因此我们可以使用标准的data.table技术。我们按“名称”分组,并创建另一个分组变量(“ind”),以便相邻的两个元素归入一个组。在下一步中,我们根据'Name'和'ind'进行分组,得到'ID'的nchar
,substr
第一个元素,该元素基于nchar
的max
和min
,将其与第二个元素粘贴在一起(这是基于提供的示例。如果先出现小于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
数据
df1可能df$ID感谢akrun这么快的回复,但是我在发布问题后意识到问题并不是那么简单。还有其他问题。在不知道其他问题的情况下,其他人很难提供解决方案。是的,我对问题做了更改,我希望没问题。cod会发生什么e如果有三组数字而不是两组?或者如果有多组长度不同?例如,可能是151314/13/19/177161/62@A.Koirala正如我前面提到的,您必须展示一个模仿原始数据集的示例。代码基于您展示的示例。
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
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))