R 从单个列创建多个列并清理结果
我有这样一个数据框:R 从单个列创建多个列并清理结果,r,split,tidyr,R,Split,Tidyr,我有这样一个数据框: foo=data.frame(Point.Type = c("Zero Start","Zero Start", "Zero Start", "3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww","3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww","3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww","Zero Stop","Zero Start"), Point.Val
foo=data.frame(Point.Type = c("Zero Start","Zero Start", "Zero Start", "3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww","3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww","3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww","Zero Stop","Zero Start"),
Point.Value = c(NA,NA,NA,rnorm(3),NA,NA))
我想通过使用分隔符\uu
拆分第一列来添加三列,并且只保留拆分后获得的数值。对于第一列不包含任何的行,三个新列应为NA
。我使用separate
获得了一些成功,但这还不够:
> library(tidyr)
> bar = separate(foo,Point.Type, c("rpm_nom", "GVF_nom", "p0in_nom"), sep="_", remove = FALSE, extra="drop", fill="right")
> bar
Point.Type rpm_nom GVF_nom p0in_nom Point.Value
1 Zero Start Zero Start <NA> <NA> NA
2 Zero Start Zero Start <NA> <NA> NA
3 Zero Start Zero Start <NA> <NA> NA
4 3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww 3000rpm 10% 13barG -1.468033
5 3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww 3000rpm 10% 13barG 1.280868
6 3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww 3000rpm 10% 13barG 0.270126
7 Zero Stop Zero Stop <NA> <NA> NA
8 Zero Start Zero Start <NA> <NA> NA
>库(tidyr)
>条=单独的(foo,Point.Type,c(“rpm_nom”,“GVF_nom”,“p0in_nom”),sep=“”,remove=FALSE,extra=“drop”,fill=“right”)
>酒吧
点。键入rpm_nom GVF_nom p0in_nom Point.Value
1零开始零开始NA
2零开始零开始NA
3零开始零开始NA
4 3000rpm_10%_13barG_SDSA_1.0_不锈钢Pww 3000rpm 10%13barG-1.468033
5 3000rpm 10%13barG SDSA 1.0不锈钢Pww 3000rpm 10%13barG 1.280868
6 3000rpm 10%13barG SDSA 1.0不锈钢Pww 3000rpm 10%13barG 0.270126
7零停止零停止NA
8零开始零开始NA
我不知道为什么我的数据框现在包含两种明显不同的NA
,但是。NA
似乎喜欢这两种,所以我可以接受。但是,我有两种问题:
新列应至少为数值
,也可能为整数
。相反,它们是字符
,因为尾随rpm
,%
,barG
。我怎样才能摆脱这些
当无法拆分点类型时,rpm\u nom
应为NA
,而变为零开始
或零停止
。更改fill=
选项只会更改新列中获得Zero Start
/Zero Stop
的列。相反,我希望这三个都是NA
。我该怎么做
注意:我使用的是tidyr
,但如果您认为有更好的方法,当然不需要这样做。您可以使用dplyr对列进行后期处理:
或者使用data.table(由@DavidArenburg在评论中提供):
将产生类似的结果:
> foo
Point.Type Point.Value rpm_nom GVF_nom p0in_nom
1: Zero Start NA NA NA NA
2: Zero Start NA NA NA NA
3: Zero Start NA NA NA NA
4: 3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww -0.09255445 3000 10 13
5: 3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww 1.18581340 3000 10 13
6: 3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww 2.14475950 3000 10 13
7: Zero Stop NA NA NA NA
8: Zero Start NA NA NA NA
这样做的好处是,foo
通过引用进行更新。由于这种方法速度更快、内存效率更高,因此对于使用大型数据集尤其有价值。对于base R
,我们可以在必要时首先强制NA
值,并强制类数值
:
bar[-1] <- lapply(bar[-1], function(x) {
is.na(x) <- grepl("Zero", x)
as.numeric(gsub("[^0-9.]", "", x))})
# Point.Type rpm_nom GVF_nom p0in_nom Point.Value
# 1 Zero Start NA NA NA NA
# 2 Zero Start NA NA NA NA
# 3 Zero Start NA NA NA NA
# 4 3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww 3000 10 13 0.3558397
# 5 3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww 3000 10 13 1.1454829
# 6 3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww 3000 10 13 0.2958815
# 7 Zero Stop NA NA NA NA
# 8 Zero Start NA NA NA NA
bar[-1]@Jaap听起来很棒!使用%>%
,是否可以避免创建条
?@davidernburg您的解决方案看起来也不错,但是数据表是什么?我所有的代码都在data.frames上工作。我担心切换到这些数据表可能会影响代码的其余部分。另外,我不知道函数tstrsplit
,但我想它在data.table
包中有记录。@DeltaIV更新了答案。data.table
是data.frame
的一种增强形式。有关更多信息,请参阅。有趣!我的数据帧并不是很大,但比示例要大得多(大约是2000行乘1200列)。也许数据表会很好:我会研究它们。我有点遗憾地放弃了哈德利·维克汉姆的软件包,因为我喜欢它们,但是如果性能得到了实质性的提升,那么它可能是值得的!顺便说一句,您可以使用type.convert
,而不是作为.numeric
,这样它将自己正确地转换为整数和numeric
。我不确定您为什么要使用条[-1]
。另外,@Jaapgsub([^0-9],”,x)
和您的gsub([[:alpha:].[:punct:][],”,x)
之间有什么区别?最后,为什么在上一列中,您会得到10^14量级的Point.Value
srnorm(3)
应该生成更接近0的数字。bar[-1]
删除我们不想处理的第一列。这两种正则表达式模式之间的差异可以在这里看到。在最后一列中,删除了小数点。
library(data.table)
setDT(foo)[, c("rpm_nom","GVF_nom","p0in_nom") :=
lapply(tstrsplit(Point.Type, "_", fixed = TRUE)[1:3],
function(x) as.numeric(gsub("[^0-9]","",x)))
]
> foo
Point.Type Point.Value rpm_nom GVF_nom p0in_nom
1: Zero Start NA NA NA NA
2: Zero Start NA NA NA NA
3: Zero Start NA NA NA NA
4: 3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww -0.09255445 3000 10 13
5: 3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww 1.18581340 3000 10 13
6: 3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww 2.14475950 3000 10 13
7: Zero Stop NA NA NA NA
8: Zero Start NA NA NA NA
bar[-1] <- lapply(bar[-1], function(x) {
is.na(x) <- grepl("Zero", x)
as.numeric(gsub("[^0-9.]", "", x))})
# Point.Type rpm_nom GVF_nom p0in_nom Point.Value
# 1 Zero Start NA NA NA NA
# 2 Zero Start NA NA NA NA
# 3 Zero Start NA NA NA NA
# 4 3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww 3000 10 13 0.3558397
# 5 3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww 3000 10 13 1.1454829
# 6 3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww 3000 10 13 0.2958815
# 7 Zero Stop NA NA NA NA
# 8 Zero Start NA NA NA NA
bar[-1] <- lapply(bar[-1], function(x) as.numeric(gsub("[^0-9.]", "", x)))