R 尝试使用“分离”将一列拆分为两列以上

R 尝试使用“分离”将一列拆分为两列以上,r,dplyr,tidyr,kaggle,R,Dplyr,Tidyr,Kaggle,我是新手,正在练习使用卡格尔的泰坦尼克号数据集。我试图将姓、名、称呼和其他信息分为不同的列,以便我可以尝试对乘客的年龄进行分类——成人或儿童 以下是列车数据集中的样本数据: head(traindf,5) # Source: local data frame [5 x 12] # # PassengerId Survived Pclass # 1 1 0 3 # 2 2 1 1 # 3

我是新手,正在练习使用卡格尔的泰坦尼克号数据集。我试图将姓、名、称呼和其他信息分为不同的列,以便我可以尝试对乘客的年龄进行分类——成人或儿童

以下是列车数据集中的样本数据:

head(traindf,5)
# Source: local data frame [5 x 12]
# 
# PassengerId Survived Pclass
# 1           1        0      3
# 2           2        1      1
# 3           3        1      3
# 4           4        1      1
# 5           5        0      3
# Variables not shown: Name (chr), Sex (fctr), Age (dbl), SibSp (int), Parch
# (int), Ticket (fctr), Fare (dbl), Cabin (fctr), Embarked (fctr)
以下是包含名称的示例:

select(traindf,Survived,Pclass,Name,Sex)
# Source: local data frame [891 x 4]
# 
# Survived Pclass                                                Name    Sex
# 1         0      3                             Braund, Mr. Owen Harris   male
# 2         1      1 Cumings, Mrs. John Bradley (Florence Briggs Thayer) female
# 3         1      3                              Heikkinen, Miss. Laina female
# 4         1      1        Futrelle, Mrs. Jacques Heath (Lily May Peel) female
# 5         0      3                            Allen, Mr. William Henry   male
# 6         0      3                                    Moran, Mr. James   male
# 7         0      1                             McCarthy, Mr. Timothy J   male
# 8         0      3                      Palsson, Master. Gosta Leonard   male
# 9         1      3   Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg) female
# 10        1      2                 Nasser, Mrs. Nicholas (Adele Achem) female
我可以使用以下代码将姓氏与列的其余部分分开:

require(tidyr) # for the separate() function

traindfnames <- traindf %>%
  separate(Name, c("Lastname","Salutation"), sep = ",")

traindfnames 
# Source: local data frame [891 x 13]
# 
# PassengerId Survived Pclass  Lastname
# 1            1        0      3    Braund
# 2            2        1      1   Cumings
# 3            3        1      3 Heikkinen
# 4            4        1      1  Futrelle
# 5            5        0      3     Allen
# 6            6        0      3     Moran
# 7            7        0      1  McCarthy
# 8            8        0      3   Palsson
# 9            9        1      3   Johnson
# 10          10        1      2    Nasser
# ..         ...      ...    ...       ...
# Variables not shown: Salutation (chr), Sex (fctr), Age (dbl), SibSp (int),
# Parch (int), Ticket (fctr), Fare (dbl), Cabin (fctr), Embarked (fctr)

我是否使用了错误的语法或一列中的3个字段不可能

查看了这些数据后,我认为最简单的方法是使用package
stringr
中的类似
str_match()
。如果您假定
数据$Name
在表单中 “[姓氏],[称呼].[姓氏]” 与此匹配的正则表达式是

str_match(data$Name, "([A-Za-z]*),\\s([A-Za-z]*)\\.\\s(.*)")
#      [,1]                                                  [,2]        [,3]   [,4]                                   
# [1,] "Braund, Mr. Owen Harris"                             "Braund"    "Mr"   "Owen Harris"                          
# [2,] "Cumings, Mrs. John Bradley (Florence Briggs Thayer)" "Cumings"   "Mrs"  "John Bradley (Florence Briggs Thayer)"
# [3,] "Heikkinen, Miss. Laina"                              "Heikkinen" "Miss" "Laina"                                
# [4,] "Futrelle, Mrs. Jacques Heath (Lily May Peel)"        "Futrelle"  "Mrs"  "Jacques Heath (Lily May Peel)"        
# [5,] "Allen, Mr. William Henry"                            "Allen"     "Mr"   "William Henry"                        
# [6,] "Moran, Mr. James"                                    "Moran"     "Mr"   "James" 
因此,您需要将上面的第2列到第4列添加到原始数据框中。实际上,我不确定您是否可以使用
单独的
来执行此操作。书写

separate(data, Name, c("Lastname", "Salutation", "Firstname"), sep = "[,\\.]") 
将尝试用逗号或点分隔每个条目,但在第514个条目中遇到问题,看起来像“Rothschild,Martin夫人(Elizabeth L.Barrett)”(注意第二个点)

简言之,我能看到的做你想做的事情的最简单方法是

data[c("Firstname", "Salutation", "Lastname")] <-
    str_match(data$Name, "([A-Za-z]*),\\s([A-Za-z]*)\\.\\s(.*)")[, 2:4]

data[c(“名字”、“称呼”、“姓氏”)]我只是对dplyr有点着迷。对于一个非程序员来说,理解dplyr是如此容易,以至于我希望找到一个dplyr的答案。我和斯特林格一起去。感谢您的阅读。另请参见
tidyr::extract
,它为
str_match
@SandraK提供了一个方便的包装器。我强烈建议您学习一点正则表达式的知识-起初,它们看起来像是猫在键盘上走过,但一旦您掌握了它们,它们就会非常强大。@Hadley,tidyr::extract正在为此任务工作。谢谢你对正则表达式的建议。我会继续努力的。
separate(data, Name, c("Lastname", "Salutation", "Firstname"), sep = "[,\\.]") 
data[c("Firstname", "Salutation", "Lastname")] <-
    str_match(data$Name, "([A-Za-z]*),\\s([A-Za-z]*)\\.\\s(.*)")[, 2:4]