将一个列中的多个值拆分为多行 R。

21

我有一个数据框,大部分情况下每行只有一条观察记录。然而,有些行有多个数值:

# A tibble: 3 x 2
          `number`   abilities
             <dbl>       <chr>
1               51       b1261
2               57        d710
3               57 b1301; d550

structure(list(`number` = c(51, 57, 57), abilities = c("b1261", 
"d710", "b1301; d550")), .Names = c("number", "abilities"
), row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame"
))

我希望得到以下内容:

# A tibble: 3 x 2
          `number`   abilities
             <dbl>       <chr>
1               51       b1261
2               57        d710
3               57        d550
4               57       b1301

把内容用分号分隔开是比较简单的,但我不确定如何轻松地添加新行,特别是因为能力可能包含多个值。

这与R将分号分隔的列拆分为行非常相似,但不需要删除重复项。

3个回答

29

tidyr 中有一个名为 separate_rows 的函数可以实现此功能:

library(tidyr)
## The ";\\s+" means that the separator is a ";" followed by one or more spaces
separate_rows(df,abilities,sep=";\\s+")
  number abilities
   <dbl>     <chr>
1     51     b1261
2     57      d710
3     57     b1301
4     57      d550

1
我认为你需要修剪空格,或者使用 sep=";\\s+",否则最后一个条目将在开头有一个空格。 - Marius
@Marius 你说得完全正确,我没有注意到。谢谢! - Lamia
谢谢,我不知道tidyr中有这个功能。我将空格匹配调整为:";\s*",以允许零个或多个空格。 - pluke

8

dplyr在这方面很好,因为它有unnest函数:

library(tidyverse)
library(stringr)
df %>%
    mutate(unpacked = str_split(abilities, ";")) %>%
    unnest %>%
    mutate(abilities = str_trim(unpacked))

1
显然,在最近的 dplyr 版本中,对于 unnest,必须明确命名列。因此,它变成了 unnest(cols = c(unpacked)) - hannes101

1
另一个选择是cSplit
 library(splitstackshape)
 cSplit(df1, 'abilities', '; ', 'long')
 #   number abilities
 #1:     51     b1261
 #2:     57      d710
 #3:     57     b1301
 #4:     57      d550

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接