假设我有以下两个表:
表1:
id word
1 apple
1 banana
2 cherry
2 donuts
3 eggplant
3 fish
表2(key_words):
key_words
apple
orange
cherry
peach
我想检查table1的'word'列中的每个元素是否都存在于table2中,并得到以下结果:
id apple orange cherry peach
1 1 0 0 0
2 0 0 1 0
3 0 0 0 0
例如,
第一行中的1和“apple”列表示id 1确实有一个苹果
第二行为0,“orange”列表示id 2没有橙色。
为了得到这样的结果,我写了一个for循环:
data=list()
data[[1]]=table1$id
l=dim(table1)[1]
for(i in 2:(length(key_words)+1)){
exist=c()
for(j in 1:l){
d1=table1[which(table1$id==data[[1]][j]),]
if(key_words[i] %in% d1$word){
exist[j]=1
} else {
exist[j]=0
}
}
data[[i]]=exist
}
data=as.data.frame(data)
names(data)=c("id","apple","orange","cherry","peach")
确实有效。
但是,如果我的表格大小和关键字数量变得更大,例如,如果我有10,000个ID和1,000个关键字,则for循环将运行很长时间。
是否有一些更快的缩短运行时间的方法?
答案 0 :(得分:3)
library(data.table)
dat <- fread("id word
1 apple
1 banana
2 cherry
2 donuts
3 eggplant
3 fish")
dat_key <- fread("key_words
apple
orange
cherry
peach")
dat_wide <- data.table(ID = unique(dat$id))
l <- lapply(dat_key$key_words, function(x) dat_wide[, (x) := ifelse(ID %in% dat[word == x]$id, 1, 0)][])
dat_wide
ID apple orange cherry peach
1: 1 1 0 0 0
2: 2 0 0 1 0
3: 3 0 0 0 0
答案 1 :(得分:2)
data.frame(t(sapply(split(table1, table1$id), function(a)
colSums(sapply(table2$key_words, function(x) a$word %in% x)) > 0)))
# apple orange cherry peach
#1 TRUE FALSE FALSE FALSE
#2 FALSE FALSE TRUE FALSE
#3 FALSE FALSE FALSE FALSE
如果需要,可以在另一个步骤中将布尔值更改为数字
temp = data.frame(t(sapply(split(table1, table1$id), function(a)
colSums(sapply(table2$key_words, function(x) a$word %in% x)) > 0)))
data.frame(sapply(temp, as.numeric), row.names = row.names(temp))
# apple orange cherry peach
#1 1 0 0 0
#2 0 0 1 0
#3 0 0 0 0
数据强>
table1 = structure(list(id = c(1L, 1L, 2L, 2L, 3L, 3L), word = c("apple",
"banana", "cherry", "donuts", "eggplant", "fish")), .Names = c("id",
"word"), class = "data.frame", row.names = c(NA, -6L))
table2 = structure(list(key_words = c("apple", "orange", "cherry", "peach"
)), .Names = "key_words", class = "data.frame", row.names = c(NA,
-4L))