r - 从单个列创建多个列并清理结果

标签 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.Value = c(NA,NA,NA,rnorm(3),NA,NA))

我想添加三列,通过使用分隔符 _ 拆分第一列,并仅保留拆分后获得的数值。对于第一列不包含任何 _ 的行,三个新列应为 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

我不确定为什么我的数据框现在包含两种明显不同的 NA,但 is.na 似乎都喜欢它们,所以我可以忍受那。但是,我有两类问题:

  1. 新列应至少为数字,也可能为整数。相反,它们是字符,因为后面有rpm%barG。我该如何摆脱这些?
  2. Point.Type无法拆分时,rpm_nom应该为NA,而不是Zero Start > 或零停止。更改 fill= 选项只会更改获得 Zero Start/Zero Stop 的新列之一。相反,我希望它们全部都是 NA。我怎样才能做到这一点?

注意:我正在使用 tidyr,但如果您认为有更好的方法来执行此操作,当然您不需要这样做。

最佳答案

您可以使用 dplyr 对列进行后处理:

library(dplyr)
foo <- foo %>%
  separate(Point.Type, c("rpm_nom", "GVF_nom", "p0in_nom"), 
           sep="_", remove = FALSE, extra="drop", fill="right") %>%
  mutate_each(funs(as.numeric(gsub("[^0-9]","",.))), rpm_nom, GVF_nom, p0in_nom)

gsub("[^0-9]","",.) 部分删除所有非数字字符。如果您想阻止删除小数点,可以使用 [^0-9.] 而不是 [^0-9] (就像@PierreLafortune在他的回答中使用的那样),但请注意,这也将包括不应该是小数点的点。通过将其包装在 as.numeric 中,您可以将它们转换为数值,同时将空单元格转换为 NA。这给出了以下结果:

> foo
                            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  -1.2361145
5 3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww    3000      10       13  -0.8727960
6 3000rpm_10%_13barG_Sdsdsa_1.0_ss_Pww    3000      10       13   0.9685555
7                            Zero Stop      NA      NA       NA          NA
8                           Zero Start      NA      NA       NA          NA

或者使用data.table(由@DavidArenburg在评论中提供):

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

这样做的好处是 foo 通过引用进行更新。由于这更快且内存效率更高,因此对于使用大型数据集特别有值(value)。

关于r - 从单个列创建多个列并清理结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35202797/

相关文章:

R:如何添加 L1 范数线以从 glmnet 绘图

r - 为相同的向量组合获取不同的相关值

Java RegEx 查找,引号之间除外

awk - 使用 AWK 或 SED 获取每一行的第一个词?

r - 具有重复列名的整洁 data.frame

javascript - R 传单包产生空白(灰色) map [Ubuntu 14.04]

r - 拆分包含字符的日期

javascript - 将单个字段分隔为名称、名字和姓氏

r - 与 tidyr 中的 Spread 混淆

r - 将行与列匹配并计算相同的出现次数 R