【问题标题】:Creating multiple dataframes out of one based on string search in R基于 R 中的字符串搜索从一个数据帧中创建多个数据帧
【发布时间】:2017-06-28 23:03:04
【问题描述】:

我对 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 循环?)

任何建议将不胜感激。

【问题讨论】:

  • 无论如何找到 PMID,您打算如何拆分成更小的 DF?
  • 这也是我需要帮助的...我不想手动创建 df1 <- original[1:10, ]
  • 我在想也许可以找到每个 PMID 的索引并以某种方式创建从第 1 到第 4000、第 4001 到第 8000 等的多个数据帧……如果有的话,我想手动创建 100- 200 个数据帧并不是可能发生的最糟糕的事情......我只是不知道如何以均匀的间隔找到 PMID

标签: r string dataframe split


【解决方案1】:

每当你击中一个新组的开始时,做一个小反击,然后分开。这是一个简化的示例:

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)

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

【讨论】:

  • 大声笑在运行该脚本后,我的 R 冻结了我的计算机,所以我不得不重新启动它。我想我需要手动将 1000 万行拆分为 100 万行,然后在每一百万行上使用您的代码(这也是拆分 l o l)......我的示例数据框已简化;每个 PMID 后面大约有 20 行,我也讨厌我的 R 不能处理 1000 万行。会及时更新,但我看到你的代码有很多潜力!
  • @sweetmusicality - 如果您正在处理大量数据,那么可能值得查看 data.table 或 dplyr。您可以将(cumsum(... grpsize 上方的计数器用作“分组/分组依据”来更快地进行操作。
  • 嗯。我也会调查一下。谢谢你!现在我的 R 正在运行grepl("^PMID", df),这样我就可以根据索引接近百万的 PMID 手动将 1000 万行拆分为 100 万行的十个数据帧(我的 R 仍在运行……我的代码对吗? )
  • @sweetmusicality - grepl("^PMID", df$var) - 你需要在某处引用 var - 无论你的列包含所有文本在 df 中被称为什么
  • @sweetmusicality - 是的,如果df 实际上是data.frame - 检查class(df) - 那么你必须引用变量,而不是整个对象。完成grepl 应该是几秒钟,而不是几分钟 - 我只是在 1 秒内对 10M 记录运行了代码。
【解决方案2】:

所以虽然@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 分钟。

【讨论】:

    猜你喜欢
    • 2020-09-18
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    • 2022-08-12
    • 1970-01-01
    • 2022-08-06
    • 2020-07-01
    • 2019-07-29
    相关资源
    最近更新 更多