簡體   English   中英

R:為具有部分字符串匹配的一組列名查找每行 > 0 的列數

[英]R: find number of columns > 0 per row for a group of column names with a partial string match

我有一個類似於以下內容的數據框:

ID X A_1_l A_2_m B_1_n B_2_l C_1_m C_2_n C_3_l
X 0 0 0 0 0 0 0
X X 0 0 3 0 0 0 0
X 0 1 0 4 0 1 0
z X 3 4 5 6 2 1 5

第一個字母表示樣品,數字表示重復,第二個字母表示批次。 我正在嘗試為每個 ID 找到至少一個值 > 0 的樣本數,並將這些數字存儲在列表中。

這是作為我可以附加到現有數據幀的列表所需的結果:

0,1,3,3

在之前的分析中,我使用strsplit來計算每批的樣本總數。

colsList <- colnames(df)
cols <- grep("_", colsList, value=TRUE)
splitList <- strsplit(cols, "_\\d_")
stats <-data.frame(t(as.data.frame.list(splitList)))
rownames(stats)<-NULL
names(stats)<-c("Sample", "Batch")
perSample <- aggregate(Sample ~ Batch, stats, 
                      function(x) length(unique(x))) # number of strains

我能夠使用rowSums(df[sapply(df, is.numeric)] > 0)找到值 > 0 的列總數rowSums(df[sapply(df, is.numeric)] > 0)但我似乎無法弄清楚如何將兩者結合起來找到總數樣本數 > 0

首先過濾數據以僅保留數字列。

使用split.default將數據分組,以便您將所有'A'列放在一組中, 'B'放在另一組中,依此類推。 在每一組返回TRUE如果一個行都有一個值,該值大於0, sum從所有組中的所有值加在一起得到最終計數。

tmp <- Filter(is.numeric, df)

rowSums(sapply(split.default(tmp, sub('_.*', '', names(tmp))), 
        function(x) rowSums(x) > 0))

#[1] 0 1 3 3

我們可以在tidyverse做到這tidyverse

library(dplyr)
library(stringr)
library(tidyr)
df1 %>%  
    select(ID, where(is.numeric)) %>%
    pivot_longer(cols = -ID) %>%
    mutate(name = str_remove(name, "_.*")) %>% 
    group_by(ID, name) %>% 
    summarise(value = sum(value > 0), .groups = 'drop_last') %>% 
    summarise(value = sum(value > 0))
# A tibble: 4 x 2
  ID    value
  <chr> <int>
1 w         0
2 x         1
3 y         3
4 z         3

數據

df1 <- structure(list(ID = c("w", "x", "y", "z"), X = c("X", "X", "X", 
"X"), Y = c("Y", "Y", "Y", "Y"), A_1_l = c(0L, 0L, 0L, 3L), A_2_m = c(0L, 
0L, 1L, 4L), B_1_n = c(0L, 3L, 0L, 5L), B_2_l = c(0L, 0L, 4L, 
6L), C_1_m = c(0L, 0L, 0L, 2L), C_2_n = c(0L, 0L, 1L, 1L), C_3_l = c(0L, 
0L, 0L, 5L)), class = "data.frame", row.names = c(NA, -4L))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM