R

时间:2018-07-25 19:37:28

标签: r loops if-statement grepl

我想创建一个快速函数,如果一列中包含的字符串与我的一列相同,则返回true或false。 true或false将在单独命名的列中注册。下面是数据结构的示例:

df = data.frame(Authors, A1, A2 [... all the way A63])
# Example of "Authors" column row values: ("A1, A12, A50")
# All other columns equal: NA
# Note: "Authors" has millions of rows.

我有一个嵌套循环,可从通常包含多个这样的“作者” /“ df [,1]”(例如:“ A1,A12,A50”)的列中识别出作者的名字“ A1”,并返回“如果在该字符串中包含作者的姓名,则将“ True”放入以特定作者(“ A12”)命名的列中(或者,为“ False”)。这是一个缓慢的嵌套循环,可以达到预期的结果:

for (i in 2:length(df)){
    for (j in 1:nrow(df)) {
df[j,i]= ifelse(grepl(df[j,1],colnames(df[i])), TRUE, FALSE)}}
# Intended result df[2,2] = "True" if df[2,1] = ("A1, A2, A50"), otherwise "False".

以上方法有效,但是速度非常慢。我有数百万行。 关于如何加快速度的任何指示?

编辑:以下是通过dput我的数据框的外观:

structure(list(Authurs = c("A. Trevor Thrall", "A. Trevor Thrall", 
"A. Trevor Thrall", "A. Trevor Thrall, Benjamin H. Friedman", 
"A. Trevor Thrall, Benjamin H. Friedman", "A. Trevor Thrall, Benjamin H. Friedman, Christopher A. Preble, Peter Russo", 
"A. Trevor Thrall, Caroline Dorminey", "A. Trevor Thrall, Caroline Dorminey", 
"A. Trevor Thrall, Caroline Dorminey", "A. Trevor Thrall, Caroline Dorminey", 
"A. Trevor Thrall, Caroline Dorminey", "A. Trevor Thrall, Caroline Dorminey", 
"A. Trevor Thrall, Caroline Dorminey", "A. Trevor Thrall, Caroline Dorminey", 
"A. Trevor Thrall, Caroline Dorminey"), `Jeffrey A. Singer` = c(NA_character_, 
NA_character_, NA_character_, NA_character_, NA_character_, NA_character_, 
NA_character_, NA_character_, NA_character_, NA_character_, NA_character_, 
NA_character_, NA_character_, NA_character_, NA_character_), 
    `Caroline Dorminey` = c(NA_character_, NA_character_, NA_character_, 
    NA_character_, NA_character_, NA_character_, NA_character_, 
    NA_character_, NA_character_, NA_character_, NA_character_, 
    NA_character_, NA_character_, NA_character_, NA_character_
    ), `Eric Gomez` = c(NA_character_, NA_character_, NA_character_, 
    NA_character_, NA_character_, NA_character_, NA_character_, 
    NA_character_, NA_character_, NA_character_, NA_character_, 
    NA_character_, NA_character_, NA_character_, NA_character_
    ), `John Samples` = c(NA_character_, NA_character_, NA_character_, 
    NA_character_, NA_character_, NA_character_, NA_character_, 
    NA_character_, NA_character_, NA_character_, NA_character_, 
    NA_character_, NA_character_, NA_character_, NA_character_
    ), `Emma Ashford` = c(NA_character_, NA_character_, NA_character_, 
    NA_character_, NA_character_, NA_character_, NA_character_, 
    NA_character_, NA_character_, NA_character_, NA_character_, 
    NA_character_, NA_character_, NA_character_, NA_character_
    )), row.names = c(NA, 15L), class = "data.frame")

1 个答案:

答案 0 :(得分:1)

我修改了您的对象片段,使其具有一定的实际点击率。

df <- 
structure(list(Authors = c("A. Trevor Thrall", "A. Trevor Thrall", 
"A. Trevor Thrall", "A. Trevor Thrall, Benjamin H. Friedman", 
"A. Trevor Thrall, Benjamin H. Friedman", "A. Trevor Thrall, Benjamin H. Friedman, Christopher A. Preble, Peter Russo", 
"A. Trevor Thrall, Caroline Dorminey", "A. Trevor Thrall, Caroline Dorminey", 
"A. Trevor Thrall, Caroline Dorminey", "A. Trevor Thrall, Caroline Dorminey", 
"A. Trevor Thrall, Caroline Dorminey", "A. Trevor Thrall, Caroline Dorminey", 
"A. Trevor Thrall, Caroline Dorminey", "A. Trevor Thrall, Caroline Dorminey", 
"A. Trevor Thrall, Caroline Dorminey"), `A. Trevor Thrall` = c(TRUE, 
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
TRUE, TRUE, TRUE), `Benjamin H. Friedman` = c(FALSE, FALSE, FALSE, 
TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE), `Christopher A. Preble` = c(FALSE, FALSE, FALSE, 
FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE), `Peter Russo` = c(FALSE, FALSE, FALSE, 
FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE), `Caroline Dorminey` = c(FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
TRUE, TRUE)), row.names = c(NA, 15L), class = "data.frame")

现在有一些热门歌曲,请尝试以下操作:

df[-1] <- lapply(names(df[-1]), function(nm) grepl(nm, df[[1]]))

它循环遍历每个非“ Authors”列名,并根据“ Authors”列中是否有grepl-hit设置TRUE或FALSE。我认为这就是您所要的,并且向您保证,它比通过ifelse测试的双嵌套循环要快得多。我消除的是内部循环,并用向量化操作代替了它。由于lapplysapply的速度实际上都等效于for循环,因此外部循环基本上没有变化。重要的是循环中的算法。