使用 plyr::mutate 以矢量化方式提取列表部分?
Extract list parts in a vectorized way with plyr::mutate?
假设这段代码:
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$two
成为 c(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"
我们可以使用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
您可以使用 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
假设这段代码:
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$two
成为 c(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"
我们可以使用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
您可以使用 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