基于R中的字符串搜索创建多个数据帧

时间:2017-06-28 23:03:04

标签: r string dataframe split grep

我对R比较陌生。我的数据框超过1000万行,包含500,000个PMID(一种ID)。但是,我用来运行它的代码最多只能处理4000-5000个PMID。下面是原始数据框(它在一列中的所有内容)的样本:

PMID- 28524368 OT - cardiomyopathy OT - encephalitis LID - 10.1111/jmp.12273 [doi] PL - Denmark PMID- 28523858 OT - Pan troglodytes PST - aheadofprint LID - 10.1111/echo.13561 [doi] STAT- Publisher FAU - Ruivo, Catarina PMID- 52528302 CI - (c) 2017, Wiley Periodicals, Inc. DA - 20170518 OWN - NLM PMID- 18325287 STAT- Publisher OWN - NLM DA - 20170519 LA - eng PMID- 95625132 FAU - Oumerzouk, Jawad JID - 0135232 PL - Australia PMID- 47628853 LA - eng STAT- Publisher AID - 10.1111/jmp.12273 [doi]

正如您在示例数据框中看到的,只有6个PMID。因此,为了示例,假设我需要创建多个数据帧,并且每个数据帧应该只有2个PMID(在我的实际代码中,我可能会执行大约4000个PMID)。因此,我想将我的数据帧分成3个不同的数据帧(从一个PMID开始,在第三个PMID到来之前结束)

DF1: PMID- 28524368 OT - cardiomyopathy OT - encephalitis LID - 10.1111/jmp.12273 [doi] PL - Denmark PMID- 28523858 OT - Pan troglodytes PST - aheadofprint LID - 10.1111/echo.13561 [doi] STAT- Publisher FAU - Ruivo, Catarina

DF2: PMID- 52528302 CI - (c) 2017, Wiley Periodicals, Inc. DA - 20170518 OWN - NLM PMID- 18325287 STAT- Publisher OWN - NLM DA - 20170519 LA - eng

DF3: PMID- 95625132 FAU - Oumerzouk, Jawad JID - 0135232 PL - Australia PMID- 47628853 LA - eng STAT- Publisher AID - 10.1111/jmp.12273 [doi]

请注意,每个PMID之间的行差异不同,因此必须通过匹配PMID的字符串来完成。我不知道如何在这么大的数据集上做到这一点(我怎么不手动创建数据帧?for循环?)

任何建议都将不胜感激。

2 个答案:

答案 0 :(得分:3)

每当你点击一个新组的开头时再做一个小计数器,然后拆分。这是一个简化的例子:

x <- rep(1:3,5)
grpsize <- 2
split(x, (cumsum(x==1)+grpsize-1) %/% grpsize)
#$`1`
#[1] 1 2 3 1 2 3
#
#$`2`
#[1] 1 2 3 1 2 3
#
#$`3`
#[1] 1 2 3

在您的完整数据上,您可以使用grepl来识别每个组的开头:

split(df, (cumsum(grepl("^PMID",df$var)) + grpsize - 1) %/% grpsize)

可以说,您可以将计数器添加为数据集中的新列,并将其用作标识符,从长数据集转换为宽数据集。

答案 1 :(得分:0)

所以尽管@thelatemail的解决方案看起来很有希望,但它对我的数据集无效。即使我在仅100万行的较小子集上尝试代码之后,它也会不断冻结我的计算机,我将不得不不断重新启动计算机并重新加载所有代码和大文件。也许它在数值数据上可能更好,或者可能在更少的数据上,或者可能使用data.tabledplyr,或者我只是编码错误...不确定为什么我无法实现它是正确的(我会尝试更多,但我想很快回家),但我能够提出自己的解决方案:

# shows indices of each PMID
a <- which(grepl("^PMID", df$V1))
a <- as.data.frame(a)

# creates dataframes based on indices from `a` at every 4000 PMID
df1 <- original[c(a[1, 1]:a[4000, 1]), ]
df1 <- as.data.frame(df1)

df2 <- original[c(a[4001, 1]:a[8000, 1]), ]
df2 <- as.data.frame(df2)
等等......直到df100,哈。非常繁琐,但我无法想办法不手动执行此操作......也许创建一个功能?无论如何,我的代码在几秒钟内完成,所以我没有抱怨。加上繁琐的工作无论如何只是无意识的工作,实际上只花了10-15分钟。