【问题标题】:How would I create a function to separate and average rows of this data我将如何创建一个函数来分离和平均这些数据的行
【发布时间】:2019-04-17 01:10:05
【问题描述】:

我是 R 新手,有一个大数据框,我想用列名中的单个字母分隔数据,然后在末尾附加一列,其中包含行的平均值。数据如下:

    V1          V2  V3             V4        V5       V6       V7       V8       V9      V10      
1          gene_id gene_symbol Chr        Biotype     L001P    L003P    L004P    L005P    L008P   
2  ENSG00000000003      TSPAN6   X protein_coding   31.8003  67.3098   63.033    63.83  38.6941  
3  ENSG00000000005        TNMD   X protein_coding 0.0372353  2.28841 0.032932        0 0.358512        
4  ENSG00000000419        DPM1  20 protein_coding   17.5575  43.7474  21.0119  22.9765  26.3166  
5  ENSG00000000457       SCYL3   1 protein_coding   2.68196   3.7079  3.14505  3.82323  3.32028  
6  ENSG00000000460    C1orf112   1 protein_coding  0.532179  2.46598  1.11985 0.584227  1.20095  

大约有 70 列和 13 行,您只能看到以“P”结尾的列 (V6:V10),但是在数据框下方的 39 列中它们以“t”结尾。我想知道如何将这两个“t”和“p”分开,然后表示行。

我试过applylapplygrepsplit,但似乎仍然无法将它们分开。每当我尝试应用平均值时,它都会全面返回 NA 值,现在可以确定从这里去哪里了。

【问题讨论】:

  • 看起来你导入的数据没有标题,所以列名是V1, V2, ...而不是gene_id, ...。如果您解决了这个问题,您可以使用 which(stringr::str_detect(names(yourdata), "P$")) 按编号选择列,例如 P 列。

标签: r function split average


【解决方案1】:

首先,您错误地读取了数据(可能在导入时选择了header = FALSE)。看起来您的第一行应该是您的标题,而您的实际数据从第 2 行开始。

names(df) <- df[1, ] #Give 1st row as column names
df  <- df[-1, ]      #Delete 1st row

有一次,让我们找出以"t""P" 结尾的列

cols <- grep("P$|t$", names(df))

由于我们之前弄乱了第一行,所以列的类型已经改变,我们需要将 cols 转换为数字

df[cols] <- lapply(df[cols], as.numeric)

现在,我们可以使用rowMeans 获取这些行中的mean

df$Mean <- rowMeans(df[cols], na.rm = TRUE)

我不清楚你是想一起或单独计算以"P""t" 结尾的列的mean。以上是一起计算的。如果你想单独计算它们,你可以这样做

p_cols <- grep("P$", names(df))
t_cols <- grep("t$", names(df))
df[c(p_cols, t_cols)] <- lapply(df[c(p_cols, t_cols)], as.numeric)
df$P_Mean <- rowMeans(df[p_cols], na.rm = TRUE)
df$T_Mean <- rowMeans(df[t_cols], na.rm = TRUE)

【讨论】:

  • 对不起,不清楚,我希望每个单独的行(每个基因)都有一个平均值。此外,当使用cols &lt;- grep("P$|t$", names(df)) 时,它会将整数显示为空。我该怎么办呢
  • @NewToR 你做了第一部分吗?更改列名并删除第一行? names(df) &lt;- df[1, ] ;df &lt;- df[-1, ] ?这样做之后,您是否看到以 Pt 结尾的列名?
  • 是的,我已经完成了 names(df) &lt;- df[1, ]df &lt;- df[-1, ]。但是,一旦执行names(df) &lt;- df[1, ],V1、V2 等就会被这些列中不同值的数量所取代(例如,在染色体列上显示 23)。如果我要删除这些 V1、V2 标题,我应该names(df) &lt;- NULL吗?
  • @NewToR 也许您的数据中有因子列。让我们从头开始。首先将所有数据转换为字符。 . df[] &lt;- lapply(df, as.character) 然后应用名称names(df) &lt;- df[1, ],然后删除行df &lt;- df[-1, ] names(df) 现在是什么?并检查cols 以及cols &lt;- grep("P$|t$", names(df))
  • 啊,是的,这似乎已经解决了整数问题。但是我需要将 P 列和 T 列分成它们自己的数据框,这样我就可以分别表示行
【解决方案2】:

这里是data.table 方法:

由于您没有提供任何可重现的示例数据,我不得不捏造一个:

# load library

library(data.table)

# create data.table as the column binding of some letters and some numbers

dt <- cbind(data.table(x = LETTERS[1:5]), 
            as.data.table(matrix(sample(1:30, 30, FALSE), 
                                 nrow = 5)))

# the names aren't right, so we need to fix them according to your requirement:

names(dt) <- c("x", "1T", "2T", "3T", "1P", "2P", "3P")

现在是工作部分:我们将创建一个列(这就是:= 的用途),它在某些列(即.SD)上应用了平均值(即applymean 函数)我们需要定义(这是.SDcols 部分)。 但是这个定义是动态的,取决于列名的最后一个字母,所以我们使用grep

dt[, averageTs := apply(.SD, 1, mean), .SDcols = grep("T$", names(dt))]

在这里,我们正在寻找字符串末尾的 T,我们将要搜索的向量是 data.table 本身的 names 的向量。

为 Ps 做同样的命令,当然是用 Ts 代替 Ps。

dt[, averagePs := apply(.SD, 1, mean), .SDcols = grep("P$", names(dt))]

【讨论】:

    猜你喜欢
    • 2019-01-20
    • 1970-01-01
    • 2023-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多