【问题标题】:Add new column to a data.table; created using assign in loop向 data.table 添加新列;使用循环中的分配创建
【发布时间】:2016-07-23 08:26:07
【问题描述】:

我有一个 data.frame keywordsCategory,其中包含一组短语,我想根据我要检查的单词对其进行分类。

例如,我的“检查项”之一是 test1,对应于类别 cat1。由于我的 data.frame 的第一个观察结果是 This is a test1,因此我需要在新列 category 中包含相应的类别。

因为一个观察可以分配给多个类别,我认为最好的选择是使用 grepl 创建我的 data.frame 的独立子集,以便最近将所有内容绑定到一个新的 data.frame 中

library(data.table)

wordsToCheck <- c("test1", "test2", "This")
categoryToAssign <- c("cat1", "cat2", "cat3")

keywordsCategory <- data.frame(Keyword=c("This is a test1", "This is a test2"))

for (i in 1:length(wordsToCheck)) {
        myOriginal <- wordsToCheck[i]
        myCategory <- categoryToAssign[i]
        dfToCreate <- paste0("withCategory",i)
        assign(dfToCreate, 
               data.table(keywordsCategory[grepl(paste0(".*",myOriginal,".*"),
                                                 keywordsCategory$Keyword)==TRUE,]))
        # this wont work :(
        # dfToCreate[,category:=myCategory]
}

# Create a list with all newly created data.tables
l.df <- lapply(ls(pattern="withCategory[0-9]+"), function(x) get(x))

# Create an aggregated dataframe with all Keywords data.tables
newdf <- do.call("rbind", l.df)

子集 > rbind 有效,但我无法将相应的类别分配给我新创建的 data.tables。如果我取消注释该行,我会收到以下错误:

:=(category, myCategory) 中的错误:检查 is.data.table(DT) == TRUE。否则, := 和 :=(...) 被定义为 在 j 中使用,仅一次且以特定方式使用。请参阅帮助(“:=”)。

但是,如果我在循环完成后手动添加列,f.i:

withCategory1[,category:=myCategory]

工作正常,表格输出符合预期:

> withCategory1
                V1 category
1: This is a test1     cat2

tableOutput <- structure(list(V1 = structure(1L, .Label = c("This is a test1", 
"This is a test2"), class = "factor"), category = "cat2"), .Names = c("V1", 
"category"), row.names = c(NA, -1L), class = c("data.table", 
"data.frame"), .internal.selfref = <pointer: 0x00000000001f0788>)

当使用 assign 函数在循环内创建新列时,向 data.table 添加新列的最佳/最安全方法是什么?该解决方案不需要使用 data.tables,因为我只使用它是因为我的真实数据有数百万个观察值,并且我认为 data.table 会更快。

【问题讨论】:

  • 请附上说明问题的reproducible example
  • 谢谢。在代码中添加了一个可重现的最小示例数据集
  • 您好,请添加所需的输出表。
  • 谢谢。为问题添加了预期输出。
  • 这不是您使用 data.table 的方式。请描述您想要实现的目标。

标签: r data.table assign


【解决方案1】:

作为 for 循环的替代方案,您可以使用 paste0mapplygrepl 的组合来获得所需的内容:

# create a 'data.table'
newDT <- as.data.table(keywordsCategory)

# assign the correct categories to each row
newDT[, category := paste0(categoryToAssign[mapply(grepl, wordsToCheck, Keyword)], collapse = ','), 1:nrow(newDT)]

给出:

> newDT
           Keyword  category
1: This is a test1 cat1,cat3
2: This is a test2 cat2,cat3

如果您想在每一行上将类别列扩展为一个类别,请参阅this Q&A 了解如何做到这一点的几种方法。例如:

library(splitstackshape)
cSplit(newDT, 'category', ",", direction = 'long')

你得到:

           Keyword category
1: This is a test1     cat1
2: This is a test1     cat3
3: This is a test2     cat2
4: This is a test2     cat3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多