如何根据data.table中的多个条件设置新列?

时间:2015-09-18 09:00:49

标签: r data.table

我正在尝试根据文本搜索收集目录信息。在列Text中搜索特定字符串,并将一些说明放入新列C_Organization

以下是示例数据:

# load packages:
pacman::p_load("data.table",
               "stringr")

# make sample data:
DE <- data.table(c("John", "Sussan", "Bill"),
                 c("Text contains MIT", "some text with Stanford University", "He graduated from Yale"))

colnames(DE) <- c("Name", "Text")

> DE
     Name                               Text
1:   John                  Text contains MIT
2: Sussan some text with Stanford University
3:   Bill             He graduated from Yale

搜索某个字符串并使用新列创建一个新的data.table:

mit <- DE[str_detect(DE$Text, "MIT"), .(Name, C_Organization = "MIT")]
yale <- DE[str_detect(DE$Text, "Yale"), .(Name, C_Organization = "Yale")]
stanford <- DE[str_detect(DE$Text, "Stanford"), .(Name, C_Organization = "Stanford")]

# bind them together:
combine_table <- rbind(mit, yale, stanford)

combine_table

     Name C_Organization
1:   John            MIT
2:   Bill           Yale
3: Sussan       Stanford

这种 pick-and-combine 方法运行正常,但似乎有点单调乏味。是否可以在data.table中一步完成?

修改

由于我糟糕的数据分析技巧和不清洁的数据,我需要明确问题:

  1. 真实数据有点复杂:

    (1)有些人来自两个以上的组织,例如Jack, UC Berkeley, Bell lab。和

    (2)同一组织的同一个人在不同年份出现,例如Steven, MIT, 2011Steven, MIT, 2014

  2. 我想弄清楚:

    (1)每个组织有多少人。如果一个人属于多个组织,则将组织作为其组织。 (即受欢迎程度。)例如,John, MIT, AMS, Bell lab,如果MIT出现30次,AMS出现12次,Bell lab出现26次。然后将MIT作为他的组织。

    (2)计算每年有多少人。这不是我原来问题的直接问题,但为了以后的计算,我不想丢掉这些记录。

1 个答案:

答案 0 :(得分:0)

考虑到一个文本中的多个匹配项的替代解决方案,以行方式操作并将匹配项绑定在一起:

uni <- c("MIT","Yale","Stanford")
DE[,idx:=.I][, c_org := paste(uni[str_detect(Text, uni)], collapse=","), idx]

这给出了:

> DE
     Name                                   Text idx             c_org
1:   John                      Text contains MIT   1               MIT
2: Sussan     some text with Stanford University   2          Stanford
3:   Bill He graduated from Yale, MIT, Stanford.   3 MIT,Yale,Stanford
4:   Bill                              some text   4                  

当您在Name中使用相同的名称时,行方向操作的优势很明显。当你这样做时:

DE[, uni[str_detect(Text, uni)], Name]

你得不到正确的结果:

     Name       V1
1:   John      MIT
2: Sussan Stanford
3:   Bill      MIT
4:   Bill Stanford

=&GT;你不知道你在第四排中有哪一张账单。此外,Yale不包括在“第一个”比尔中(即原始数据集的第3行)。

使用过的数据:

DE <- structure(list(Name = c("John", "Sussan", "Bill", "Bill"), Text = c("Text contains MIT", "some text with Stanford University", "He graduated from Yale, MIT, Stanford.", "some text")), .Names = c("Name", "Text"), row.names = c(NA, -4L), class = c("data.table", "data.frame"))