【问题标题】:Counting number of words, seperated by comma ",", in each column of a data frame in R计算R中数据框每一列中的单词数,用逗号“,”分隔
【发布时间】:2018-05-02 22:55:09
【问题描述】:

我有一个从The Human Protein Atlas 下载的数据集,其中包含 12,004 种蛋白质的亚细胞定位注释。这个文件我有子集只包括“基因名称”,然后是 4 列,说明该位置的可靠性(基于免疫荧光染色的细胞)。这些论文是“已验证”>“支持”>“已批准”>“不确定”。

我想出了一个评分系统,我想将其应用于我拥有的 LC-MS 光谱计数数据集,方法是 1) 衡量注释的质量,以及 2) 惩罚在 image of proposed scoring system 中找到的蛋白质位置。

TLDR 是我需要计算以下数据集的每一列中有多少个术语,并获取此信息的数据框。

df <- read.csv("proteinAtlas.csv")
dput(df)
structure(list(Gene_symbol = structure(1:49, .Label = c("AAAS", 
"AAMP", "AAR2", "AARD", "AARS", "AARS2", "AARSD1", "ABCA13", 
"ABCB6", "ABCB7", "ABCB8", "ABCC1", "ABCC4", "ABCD3", "ABCE1", 
"ABCF1", "ABCF2", "ABCF3", "ABHD10", "ABHD14B", "ABHD6", "ABI1", 
"ABI2", "ABL2", "ACAA1", "ACAA2", "ACACA", "ACAD9", "ACADM", 
"ACADS", "ACADVL", "ACAP1", "ACAP2", "ACAT1", "ACAT2", "ACBD3", 
"ACBD5", "ACIN1", "ACLY", "ACO2", "ACOT1", "ACOT13", "ACOT2", 
"ACOT7", "ACOT8", "ACOT9", "ACOX1", "ACP1", "ACP5"), class = "factor"), 
    Validated = structure(c(1L, 2L, 1L, 1L, 2L, 4L, 1L, 1L, 3L, 
    1L, 1L, 1L, 1L, 5L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    5L, 1L, 1L, 4L, 4L, 1L, 1L, 1L, 1L, 4L, 1L, 1L, 5L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 6L, 1L, 1L), .Label = c("", "Cytosol", 
    "Golgi apparatus", "Mitochondria", "Peroxisomes", "Vesicles"
    ), class = "factor"), Supported = structure(c(1L, 9L, 1L, 
    1L, 1L, 1L, 1L, 1L, 5L, 10L, 10L, 12L, 1L, 1L, 1L, 1L, 4L, 
    1L, 1L, 6L, 1L, 3L, 1L, 11L, 1L, 10L, 2L, 1L, 1L, 10L, 10L, 
    1L, 1L, 1L, 4L, 8L, 1L, 11L, 7L, 10L, 1L, 1L, 1L, 4L, 13L, 
    1L, 1L, 1L, 1L), .Label = c("", "Actin filaments;Cytosol", 
    "Cell Junctions;Plasma membrane", "Cytosol", "Cytosol;Mitochondria;Nucleoplasm;Plasma membrane", 
    "Cytosol;Nucleoli;Nucleus", "Cytosol;Nucleoplasm;Plasma membrane", 
    "Golgi apparatus", "Microtubules", "Mitochondria", "Nucleoplasm", 
    "Plasma membrane", "Vesicles"), class = "factor"), Approved = structure(c(3L, 
    1L, 5L, 12L, 1L, 1L, 6L, 4L, 1L, 1L, 17L, 1L, 8L, 1L, 1L, 
    1L, 1L, 7L, 13L, 1L, 16L, 1L, 15L, 1L, 1L, 1L, 14L, 1L, 1L, 
    15L, 17L, 18L, 11L, 1L, 17L, 1L, 1L, 1L, 1L, 1L, 13L, 2L, 
    13L, 15L, 13L, 9L, 17L, 10L, 5L), .Label = c("", "Cell Junctions", 
    "Centrosome;Cytosol;Nuclear membrane", "Centrosome;Cytosol;Vesicles", 
    "Cytosol", "Cytosol;Nuclear membrane", "Cytosol;Nucleoli", 
    "Cytosol;Nucleoli;Plasma membrane", "Cytosol;Nucleoplasm;Plasma membrane", 
    "Cytosol;Nucleus", "Endosomes", "Lipid droplets", "Mitochondria", 
    "Nucleoli fibrillar center", "Nucleoplasm", "Nucleoplasm;Vesicles", 
    "Nucleus", "Vesicles"), class = "factor"), Uncertain = structure(c(1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 3L, 
    1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L), .Label = c("", "Cytosol;Plasma membrane", "Nucleoli"
    ), class = "factor")), .Names = c("Gene_symbol", "Validated", 
"Supported", "Approved", "Uncertain"), class = "data.frame", row.names = c(NA, 
-49L))

所以理想的输出应该是这样的figure,或者,如果你愿意,dput():

structure(list(Gene_symbol = structure(1:29, .Label = c("AAAS", 
"AAMP", "AAR2", "AARD", "AARS", "AARS2", "AARSD1", "ABCA13", 
"ABCB6", "ABCB7", "ABCB8", "ABCC1", "ABCC4", "ABCD3", "ABCE1", 
"ABCF1", "ABCF2", "ABCF3", "ABHD10", "ABHD14B", "ABHD6", "ABI1", 
"ABI2", "ABL2", "ACAA1", "ACAA2", "ACACA", "ACAD9", "ACADM"), class = "factor"), 
    Validated = c(NA, 1L, NA, NA, 1L, 1L, NA, NA, 1L, NA, NA, 
    NA, NA, 1L, 1L, 1L, NA, NA, NA, NA, NA, NA, NA, NA, 1L, NA, 
    NA, 1L, 1L), Supported = c(NA, 1L, NA, NA, NA, NA, NA, NA, 
    4L, 1L, 1L, 1L, NA, NA, NA, NA, 1L, NA, NA, 3L, NA, 2L, NA, 
    1L, NA, 1L, 2L, NA, NA), Approved = c(3L, NA, 1L, 1L, NA, 
    NA, 2L, 3L, NA, NA, 1L, NA, 3L, NA, NA, NA, NA, 2L, 1L, NA, 
    2L, NA, 1L, NA, NA, NA, 1L, NA, NA), Uncertain = c(NA, NA, 
    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)), .Names = c("Gene_symbol", 
"Validated", "Supported", "Approved", "Uncertain"), class = "data.frame", row.names = c(NA, 
-29L))

每一列的大部分内容都是一个用“;”分隔的字符串但是,在某些情况下,它们是诸如“核仁纤维中心”或“脂质滴”之类的术语,它们以空格分隔,应计为一个单词/术语

我找到了counting the number of words in a string in R 的示例,其中:

d <- "foo,bar,fun"
length(strsplit(d,",")[[1]]
class(d)

但这仅适用于“字符”类,而不适用于“data.frame”。

谁能建议如何在 R 中做到这一点? 非常感谢!

【问题讨论】:

  • 在提供的示例中,分隔是;,另外,你提到了空格分隔,但是有Lipid droplets这样的词被计为1。不清楚
  • 感谢您注意到错字。我编辑了我的帖子以澄清事情。我想计算术语而不是单词。 Lipid droplets 是一个包含 2 个单词的术语。我想计算用分号分隔的术语;

标签: r string dataframe


【解决方案1】:

使用base的解决方案:

result_df <- data.frame(t(apply(df,1,function(x){
    c(x[1],sapply(strsplit(as.character(x[-1]),";"),length))
})), stringsAsFactors = F)
names(result_df) <- c("Gene_symbol", "Validated", "Supported", "Approved", "Uncertain")

【讨论】:

    【解决方案2】:

    我们可以使用str_count。遍历除第一个 (lapply(df[-1], ..) 之外的列,获取 ; 的计数将其加 1,检查是否存在空字符串并将这些元素替换为 NA

    library(stringr)
    df[-1] <- lapply(df[-1], function(x) (str_count(x, ";") + 1) * NA^(as.character(x) == ""))
    

    【讨论】:

    • 我对两个答案都投了赞成票,但它没有显示出来,因为我还没有 15 名声望,而且我还不知道接受答案,但选择了你的答案,因为它最容易理解。再次感谢!
    • @MatthewJ.Oldach 是的,你需要 15 分。感谢您发布问题以便我们回答。
    猜你喜欢
    • 2021-12-25
    • 1970-01-01
    • 2019-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    相关资源
    最近更新 更多