繁体   English   中英

将新列添加到data.table; 使用分配在循环中创建

[英]Add new column to a data.table; created using assign in loop

我有一个data.frame keywordsCategory其中包含了一组,我想这取决于话我想检查与归类短语。

例如,我的“检查条件”之一是test1 ,对应于类别cat1 由于对data.frame的首次观察是“ 这是一个test1” ,因此我需要在新的列类别中包含相应的类别。

因为可以将一个观察值分配给多个类别,所以我最好的选择是使用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。 如果取消注释该行,则会出现以下错误:

错误:= (类别,myCategory):检查is.data.table(DT)== TRUE。 否则,仅在特定方式下定义一次:=和:= (...)以在j中使用。 请参阅help(“:=”)。

但是,如果在循环完成后手动添加该列,则fi:

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.tables会更快。

作为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

如果要将类别列扩展为每一行中的一个类别,请参阅此常见问题解答,以了解几种方法。 例如:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM