如果我有一个df,并且我想用sep="_"
分隔player
。这是一种明智的方法吗?我可以在不手动检查我需要多少col的情况下做到这一点?对于我的示例,很容易看出我需要将player
分离为3个新列。我有100多行。这是一种告诉我需要将player
分成多少列的方法吗?还是在不知道这些信息的情况下拆分player
?
df <- data.frame(player=c('John_Wall', 'Dirk_Nowitzki', 'Steve_Nash_try'),
points=c(22, 29, 18),
assists=c(8, 4, 15))
## current method:
df %>% separate(player, c('v1', 'v2', 'v3'), sep ="_")
我们可以使用str_count
来找到_
的计数,得到max
的计数,用'v'转换为seq
的影响,paste
(str_c
(来创建列名。如果原始列需要保留,则添加remove = FALSE
library(tidyr)
library(dplyr)
library(stringr)
df %>%
separate(player, str_c('v',
seq_len(max(str_count(.$player, '_') + 1))), sep = "_", fill = "right")
-输出
v1 v2 v3 points assists
1 John Wall <NA> 22 8
2 Dirk Nowitzki <NA> 29 4
3 Steve Nash try 18 15
或者不要使用separate
,而是尝试使用cSplit
,它会自动检测并创建这些列
library(splitstackshape)
cSplit(df, 'player', sep = '_')
points assists player_1 player_2 player_3
<num> <num> <char> <char> <char>
1: 22 8 John Wall <NA>
2: 29 4 Dirk Nowitzki <NA>
3: 18 15 Steve Nash try
如果我们想使用str_extract_all
,它会返回一个list
列,该列可以转换为具有unnest_wider
的列
library(tidyr)
df %>%
mutate(v = str_extract_all(player, "[^_]+")) %>%
unnest_wider(v, names_sep = "_")
# A tibble: 3 × 6
player points assists v_1 v_2 v_3
<chr> <dbl> <dbl> <chr> <chr> <chr>
1 John_Wall 22 8 John Wall <NA>
2 Dirk_Nowitzki 29 4 Dirk Nowitzki <NA>
3 Steve_Nash_try 18 15 Steve Nash try
或使用base R
cbind(df, read.table(text = df$player, sep = "_", fill = TRUE,
header = FALSE, na.strings = ""))
player points assists V1 V2 V3
1 John_Wall 22 8 John Wall <NA>
2 Dirk_Nowitzki 29 4 Dirk Nowitzki <NA>
3 Steve_Nash_try 18 15 Steve Nash try
如果没有软件包,您可以调整最大lengths
的`length<-`
。
strsplit(df$player, '_') |>
{(.) t(sapply(., `length<-`, max(lengths(.))))} () |>
cbind(df[setdiff(names(df), 'player')])
# 1 2 3 points assists
# 1 John Wall <NA> 22 8
# 2 Dirk Nowitzki <NA> 29 4
# 3 Steve Nash try 18 15