我有这样的数据:
x <- c("France:4|Morroco:8|Italy:2", "Scotland:6|Mexico:2", "Scotland:2")
> player_country_info <- data.frame(x)
> setnames(player_country_info, "player_country_data")
> names(player_country_info)
[1] "player_country_data"
> is.data.frame(player_country_info)
[1] TRUE
> head(player_country_info)
country_data
1 France:4|Morocco:8|Italy:2
2 Scotland:6|Mexico:2
3 Scotland:2
我喜欢中间数据框,如下所示:
player_country_data.1 player_country_data.2 player_country_data.3
France:4 Morocco:8 Italy:2
Scotland:6 Mexico:2 NA
Scotland:2 NA NA
我计划然后使用dplyr :: separate函数将上面的内容分开,就像每个列一样使用此命令。
player_country_info %>% separate( col=player_country_data.1, into=c("country_name.1","player_count.1), sep=":")
country_name.1 player_count.1 country_name.2 player.2 country_name.3 player.3
France 4 Morocco 8 Italy 2
Scotland 6 Mexico 2
Scotland 2
有更有效的方法来完成上述工作吗?也许是一步完成它的命令?或者我应该在while循环之外使用for循环处理它吗?
由于
答案 0 :(得分:3)
我们可以使用cSplit
library(splitstackshape)
cSplit(country_info, 'country_data', ':|\\|', fixed = FALSE)
如果我们只需要中间步骤
cSplit(country_info, 'country_data', '|')
或者使用tidyr
,我们使用outer
在预期输出中创建列名称向量,然后在into
中指定带有'nm1'的separate
列。
library(tidyr)
nm1 <- c(outer(c('country_name.', 'player_count.'), 1:3, FUN = paste0))
separate(country_info, country_data, into = nm1, sep="[:|]")
# country_name.1 player_count.1 country_name.2 player_count.2 country_name.3 player_count.3
#1 France 4 Morroco 8 Italy 2
#2 Scotland 6 Mexico 2 <NA> <NA>
#3 Scotland 2 <NA> <NA> <NA> <NA>
随着OP在评论中显示的新数据
separate(player_country_info2, player_country_data, into = nm1, sep="[:|]", convert= TRUE)
# country_name.1 player_count.1 country_name.2 player_count.2 country_name.3 player_count.3
#1 France 4 Morocco NA Italy 2
#2 Scotland 6 Mexico 2 <NA> NA
#3 Scotland 2 <NA> NA <NA> NA
如果这是关于效率的,另一个选项是来自tstrsplit
data.table
library(data.table)
setnames(setDT(country_info)[, tstrsplit(country_data, '[:|]', type.convert = TRUE)], nm1)[]
# country_name.1 player_count.1 country_name.2 player_count.2 country_name.3 player_count.3
#1: France 4 Morroco 8 Italy 2
#2: Scotland 6 Mexico 2 NA NA
#3: Scotland 2 NA NA NA NA
答案 1 :(得分:1)
separate
包中的tidyr
:
library(tidyr)
country_info %>%
separate(country_data,
into = sprintf('%s.%s', rep(c('country','player.count'),3), rep(1:3, each=2)))
结果:
country.1 player.count.1 country.2 player.count.2 country.3 player.count.3
1 France 4 Morroco 8 Italy 2
2 Scotland 6 Mexico 2 <NA> <NA>
3 Scotland 2 <NA> <NA> <NA> <NA>
单独自动识别:
和|
作为必须分开的字符。如果要分隔特定字符,则需要使用sep
参数指定该字符。在这种情况下,您可以使用sep = '[:|]'
。这也可以防止在缺少值时自动检测的不当行为(请参阅注释中的讨论)。
使用sprintf
,您将两个向量rep(c('country','player.count'),3)
和rep(1:3, each=2)
粘贴到一个列名称向量中,其中%s.%s
告诉sprintf
处理这两个向量是字符串向量并将它们粘贴在一起作为分隔符。有关详细信息,请参阅?sprintf
。 each
参数告诉rep
不要多次重复整个向量,而是多次重复向量的每个元素。