【问题标题】:data.frame slicing数据帧切片
【发布时间】:2012-02-01 13:00:38
【问题描述】:

我希望这个问题对于这个董事会来说不是太简单。

我已经创建了一个 data.frame df:

       CAS        Name        CID
89  13010-47-4   Lomustine         3950
90 130209-82-4   Latanoprost       5311221,5282380,46705340,3890
91 130636-43-0   Nifekalant        268083
92 130929-57-6   Entacapone        5281081

还有一个向量 vec

[1] 5282380 18471829 45923789 44308022 44266812 24883465 24867475 24867460

我想提取包含任意数量的 vec 的 df 行。我试图通过这段代码解决这个问题:

 df$GC[(df$CID %in% vec)] = 1

 df[df$GC==1,]

但是这个解决方案的问题是,我只得到了行,这些行在 CID 列中只包含一个数字。在 CID 中包含多个值的行(如第 90 行)不会出现。

这个问题有没有优雅的解决方案?

提前致谢

【问题讨论】:

    标签: string r dataframe slice


    【解决方案1】:

    鉴于您对 EDi 的回答的评论(我喜欢),我想我会提出一个建议。

    将逗号分隔的值压缩到数据框的单列中很尴尬,而且(根据我的经验)只会导致挫败感。我经常发现将它保存在一个单独的数据结构(一个列表)中更简单:

    dat <- read.table(text = "       CAS        Name        CID
       13010-47-4   Lomustine         3950
      130209-82-4   Latanoprost       5311221,5282380,46705340,3890
      130636-43-0   Nifekalant        268083
      130929-57-6   Entacapone        5281081",sep = "",header = TRUE)
    
    cid <- sapply(dat$CID,strsplit,",",USE.NAMES = FALSE)
    

    在这种形式下,事情通常更容易处理:

    ID <- c(5282380, 18471829, 45923789, 44308022, 44266812, 24883465, 24867475, 24867460, 3950)
    dat[sapply(cid,function(x) {any(x %in% as.character(ID))}),]
              CAS        Name                           CID
    1  13010-47-4   Lomustine                          3950
    2 130209-82-4 Latanoprost 5311221,5282380,46705340,3890
    

    如果您担心顺序发生变化,您始终可以使用 dat 中的行名和列表名称来保持每个项目的正确性。

    (另请注意,我的匿名函数假设 ID 最终会被 R 的范围规则找到;如果您愿意,您可以更改函数以显式传入 ID。)

    【讨论】:

    • 感谢您的提示。使用逗号分隔值真的很令人沮丧:)
    【解决方案2】:

    一种方法是使用 grep():

    > txt <- "       CAS        Name        CID
    +   13010-47-4   Lomustine         3950
    +  130209-82-4   Latanoprost       5311221,5282380,46705340,3890
    +  130636-43-0   Nifekalant        268083
    +  130929-57-6   Entacapone        5281081
    + "
    > con <- textConnection(txt)
    > df <- read.table(con, header = TRUE)
    > close(con)
    > ID <- c(5282380, 18471829, 45923789, 44308022, 44266812, 24883465, 24867475, 24867460, 3950)
    > grep(paste("\\b", ID, "\\b", sep="", collapse = "|"), dat$CID)
    [1] 1 2
    

    【讨论】:

    • 不错。仅供参考,从 R-2.14 开始,借助 R-core,您可以在单个命令 txt &lt;- read.table(text="Body of table") 中读取文本数据,避免显式打开和关闭连接。
    • @Josh:谢谢! - 不知道。
    • 感谢您的快速回答。这个解决方案的问题是,例如ID“08”会找到几行,尽管这些行只包含数字。是否可以仅选择逗号之间包含完整数字的行,例如“5282380”而不仅仅是“52823”或“2380”?
    • 除了上面 Joran 的精细方法之外,您还可以修复 EDi 的正则表达式,使其仅匹配 ID 中的确切字符串。方法如下:grep(paste("\\b", ID, "\\b", sep="", collapse = "|"), dat$CID)。 (有关详细信息,请参阅?regexp,其中解释了“符号‘\b’与单词任一边缘的空字符串匹配”。)
    • @Josh+ EDi 感谢您提供这些有用的信息。效果很好。
    猜你喜欢
    • 2021-04-02
    • 2013-07-24
    • 1970-01-01
    • 2022-11-03
    • 2019-10-29
    • 2016-12-05
    • 2019-07-22
    • 2018-10-18
    • 2017-09-04
    相关资源
    最近更新 更多