【问题标题】:R: count times per column a condition is met and row names appear in a listR:计算每列满足条件并且行名出现在列表中的次数
【发布时间】:2021-12-05 23:29:16
【问题描述】:

我有一个包含计数信息的数据框 (df1)

rownames sample1 sample2 sample3
m1 0 5 1
m2 1 7 5
m3 6 2 0
m4 3 1 0

还有第二个样本信息 (df2)

rownames batch total count
sample1 a 10
sample2 b 15
sample3 a 6

我还有两个列表,其中包含有关 m 值的信息(如果需要,可以轻松地将其转换为另一个数据框,但我宁愿不添加到计数信息中,因为它非常大)。不存在任何模式(例如偶数和奇数),我只是使用一个非常简单的示例

x <- c("m1", "m3")y <- c("m2", "m4")

我想做的是在示例信息中再添加两列。这是每个样本的每个 m 的计数,其值大于 5 并出现在列表 x 或 y 中

rownames batch total count x y
sample1 a 10 1 0
sample2 b 15 1 1
sample3 a 6 0 1

我目前的策略是列出 x 和 y 的值,然后将它们附加到 df2。到目前为止,这是我的尝试:

numX <- colSums(df1[sum(rownames(df1)>10 %in% x),])numX <- colSums(df1[sum(rownames(df1)>10 %in% x),]) 都返回一个 0 列表

numX <- colSums(df1[rownames(df1)>10 %in% x,])返回每列满足条件的计数值之和的列表

numX <- length(df1[rownames(df1)>10 %in% novel,])返回满足条件的次数(本例中为2L)

我不太确定如何解决这个问题,所以我一直在尝试。我试过寻找答案,但也许我只是在努力寻找合适的措辞。

【问题讨论】:

    标签: r dataframe subset


    【解决方案1】:

    我们可以通过rowwise 做到这一点

    library(dplyr)
    df2 %>% 
       rowwise %>%
        mutate(x = +(sum(df1[[rownames]][df1$rownames %in% x]) >= 5), 
               y = +(sum(df1[[rownames]][df1$rownames %in% y]) >= 5)) %>%
        ungroup
    

    -输出

    # A tibble: 3 × 5
      rownames batch totalcount     x     y
      <chr>    <chr>      <int> <int> <int>
    1 sample1  a             10     1     0
    2 sample2  b             15     1     1
    3 sample3  a              6     0     1
    

    或者根据数据,base R 选项将是

    out <- aggregate(. ~ grp, FUN = sum, 
         transform(df1,  grp = c('x', 'y')[1 + (rownames %in% y)] )[-1])
    df2[out$grp] <- +(t(out[-1]) >= 5)
    

    -输出

    > df2
      rownames batch totalcount x y
    1  sample1     a         10 1 0
    2  sample2     b         15 1 1
    3  sample3     a          6 0 1
    

    数据

    df1 <- structure(list(rownames = c("m1", "m2", "m3", "m4"), sample1 = c(0L, 
    1L, 6L, 3L), sample2 = c(5L, 7L, 2L, 1L), sample3 = c(1L, 5L, 
    0L, 0L)), class = "data.frame", row.names = c(NA, -4L))
    
    df2 <- structure(list(rownames = c("sample1", "sample2", "sample3"), 
        batch = c("a", "b", "a"), totalcount = c(10L, 15L, 6L)), 
    class = "data.frame", row.names = c(NA, 
    -3L))
    

    【讨论】:

    • 当我运行这个(使用你的数据输入代码)时,它会添加列,但值都是 0
    • @keenan 我通过复制/粘贴数据和代码再次检查了它。它仍然提供相同的输出。有没有什么方法你已经加载了掩盖mutate或其他功能的其他包
    • @keenan BTW,我在你的帖子中使用了 x &lt;- c("m1", "m3")y &lt;- c("m2", "m4")
    • 我可以通过使用dplyr::rowise()来完成这项工作
    • 我认为你加载了slider,其中有一个rowwise
    【解决方案2】:

    您可以创建一个命名的向量列表,并为每个rownames 计算xy 在各自sample 中的值有多少个&gt;= 5

    基础 R 选项 -

    list_vec <- list(x = x, y = y)
    
    cbind(df2, do.call(rbind, lapply(df2$rownames, function(x) 
      sapply(list_vec, function(y) {
        sum(df1[[x]][df1$rownames %in% y] >= 5)
    }))))
    
    #  rownames batch total.count x y
    #1  sample1     a          10 1 0
    #2  sample2     b          15 1 1
    #3  sample3     a           6 0 1
    

    使用tidyverse -

    library(dplyr)
    library(purrr)
    
    list_vec <- lst(x, y)
    
    df2 %>%
      bind_cols(map_df(df2$rownames, function(x) 
        map(list_vec, ~sum(df1[[x]][df1$rownames %in% .x] >= 5))))
    

    【讨论】:

    • 第一个给出错误Error in data.frame(..., check.names = FALSE) : arguments imply differing number of rows: 3, 0,第二个给出错误Error: Can't recycle ..1 (size 3) to match ..2 (size 0).
    • 我在您共享的数据上没有收到任何此类错误。与 dput 共享您的数据,以便我们重现错误并提供相应的修复。
    【解决方案3】:

    使用dplyrreshape2::melt怎么样

    df3 <- df1 %>%
      melt %>%
      filter(value >= 5) %>% 
      mutate(x = as.numeric(rownames %in% c("m1", "m3")),
             y = as.numeric(rownames %in% c("m2", "m4"))) %>%
      select(-rownames, - value) %>%
      group_by(variable) %>%
      summarise(x = sum(x), y = sum(y))
    
    df2 %>% left_join(df3, by = c("rownames" = "variable"))
    
      rownames batch total_count x y
    1  sample1     a          10 1 0
    2  sample2     b          15 1 1
    3  sample3     a           6 0 1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-07
      • 2016-12-22
      • 1970-01-01
      • 1970-01-01
      • 2021-08-13
      • 2020-01-09
      • 2020-08-29
      • 1970-01-01
      相关资源
      最近更新 更多