使用plyr :: mutate以矢量化方式提取列表部分?

时间:2015-12-31 18:01:48

标签: r list plyr

假设此代码:

foo <- data.frame(cols_val=c("NA", "1:2:3", "4:5:6"))
library(plyr)
foo <- mutate(
  foo,
  cols_list = str_split(cols_val, ":"),
  one = cols_list[1],
  two = cols_list[2])

我希望foo$one c(NA, "1", "4")foo$twoc(NA, "2", "5")。也就是说,将cols_val的值拆分为数据框的各个列。

但是,cols_list是一个列表,one == cols_list[1]是该列表的第一个元素(== cols_list[[1]]),而two == cols_list[1]。所以,我不知道如何正确地对其进行矢量化。

帮助?

> foo
  cols_val cols_list one     two
1       NA        NA  NA 1, 2, 3
2    1:2:3   1, 2, 3  NA 1, 2, 3
3    4:5:6   4, 5, 6  NA 1, 2, 3

> str(foo$cols_list)
List of 3
 $ : chr "NA"
 $ : chr [1:3] "1" "2" "3"
 $ : chr [1:3] "4" "5" "6"

2 个答案:

答案 0 :(得分:4)

您可以使用tidyr::separate()代替 plyr 。它完全符合您的要求。我们可以保留现有列(使用remove = FALSE)以及将所有新列转换为适当的类型(使用convert = TRUE)。我只使用fill = "left"来避免在不使用时发出警告。我不确定警告发生的原因。

tidyr::separate(foo, cols_val, c("one", "two", "three"), ":", 
    remove = FALSE, convert = TRUE, fill = "left")
#   cols_val one two three
# 1       NA  NA  NA    NA
# 2    1:2:3   1   2     3
# 3    4:5:6   4   5     6

答案 1 :(得分:2)

我们可以使用cSplit

library(splitstackshape)
cSplit(foo, 'cols_val', ":")
#     cols_val_1 cols_val_2 cols_val_3
#1:         NA         NA         NA
#2:          1          2          3
#3:          4          5          6

默认情况下,原始列将被删除为drop=TRUE。如果我们还需要保留原始列,请使用drop=FALSE。它还默认转换'class'

cSplit(foo, 'cols_val', ":", drop=FALSE)
#  cols_val cols_val_1 cols_val_2 cols_val_3
#1:       NA         NA         NA         NA
#2:    1:2:3          1          2          3
#3:    4:5:6          4          5          6