【问题标题】:subsetting data frame on sum of column在列总和上对数据框进行子集化
【发布时间】:2019-09-29 10:44:05
【问题描述】:

这是我之前question的后续问题

考虑到我有这样的数据框:

g1:1    4
g1:2    5
g1:3    9
g2:1    6
g2:2    2
g3:1    5
g3:2    6
g4:1    4
g4:1    1

我使用以下代码拆分:上的第一列

tab2 <- read.table("dplyrtest.txt",header=FALSE)
dput(tab2)
structure(list(V1 = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 
8L), .Label = c("g1:1", "g1:2", "g1:3", "g2:1", "g2:2", "g3:1", 
"g3:2", "g4:1"), class = "factor"), V2 = c(4L, 5L, 9L, 6L, 2L, 
5L, 6L, 4L, 1L)), class = "data.frame", row.names = c(NA, -9L
))
tab2 <- data.frame(tab2$V1, do.call(rbind, strsplit(as.character(tab2$V1),split=":")))
str(tab2)

'data.frame':   9 obs. of  3 variables:
 $ tab2.V1: Factor w/ 8 levels "g1:1","g1:2",..: 1 2 3 4 5 6 7 8 8
 $ X1     : Factor w/ 4 levels "g1","g2","g3",..: 1 1 1 2 2 3 3 4 4
 $ X2     : Factor w/ 3 levels "1","2","3": 1 2 3 1 2 1 2 1 1

tab2$X2 <- as.integer(tab2$X2)
str(tab2)

'data.frame':   9 obs. of  3 variables:
 $ tab2.V1: Factor w/ 8 levels "g1:1","g1:2",..: 1 2 3 4 5 6 7 8 8
 $ X1     : Factor w/ 4 levels "g1","g2","g3",..: 1 1 1 2 2 3 3 4 4
 $ X2     : int  1 2 3 1 2 1 2 1 1

colnames(tab2) <- c("gene","name","count")

dput(tab2)
structure(list(gene = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 
8L, 8L), .Label = c("g1:1", "g1:2", "g1:3", "g2:1", "g2:2", "g3:1", 
"g3:2", "g4:1"), class = "factor"), name = structure(c(1L, 1L, 
1L, 2L, 2L, 3L, 3L, 4L, 4L), .Label = c("g1", "g2", "g3", "g4"
), class = "factor"), count = structure(c(1L, 2L, 3L, 1L, 2L, 
1L, 2L, 1L, 1L), .Label = c("1", "2", "3"), class = "factor")), class = "data.frame", row.names = c(NA, 
-9L))

tab2 <- tab2 %>% group_by(name) %>% filter(sum(as.integer(count)) > 10)

这会给出警告,并且 tab2 中没有数据:

# A tibble: 0 x 3
# Groups:   name [1]
# … with 3 variables: gene <fct>, name <fct>, count <fct>
Warning message:
Factor `name` contains implicit NA, consider using `forcats::fct_explicit_na`

任何帮助表示赞赏?

【问题讨论】:

  • 您在任何列中有NA 值吗?您可以通过sapply(tab2, function(a) sum(is.na(a))) 来查看每列中有多少。如果您提供了一个明确的数据样本,如dput(head(tab2)) 给出的那样,这将有助于了解这一点以及更多信息。
  • 您可以查看警告信息here
  • 试试sum(as.integer(count), na.rm = TRUE) &gt; 10
  • 我的数据中没有任何 NA
  • 没有一个组的总和大于 10,因此它会将所有内容过滤掉。

标签: r split subset


【解决方案1】:

拆分步骤改变了我相信的数字。

在读取文件后尝试执行此操作。

library(tidyverse)
tab2 <- read.table("dplyrtest.txt",header=FALSE)

tab2 %>%
  separate(V1, into = c("Gene", "name")) %>%
  rename_at(3, ~"count") %>%
  group_by(Gene) %>% #OR group_by(name)
  filter(sum(count) > 10)

#  Gene  name  count
#  <chr> <chr> <int>
#1  g1    1       4
#2  g1    2       5
#3  g1    3       9
#4  g3    1       5
#5  g3    2       6

【讨论】:

  • 嗨,Ronak,这行得通。我们可以像之前的输入表一样将 Gene 和 name 列与“:”结合起来吗?
  • 是的,你可以在单独的函数中添加remove = FALSEseparate(V1, into = c("Gene", "name"), remove = FALSE)...
【解决方案2】:
tab2 %>% group_by(name) %>% summarize(sum(count))
# A tibble: 4 x 2
  name  `sum(count)`
  <fct>        <dbl>
1 g1              6.
2 g2              3.
3 g3              3.
4 g4              2.

tab2 %>% group_by(name) %>% filter(sum(as.integer(count)) > 5)
# A tibble: 3 x 3
# Groups:   name [1]
  gene  name  count
  <fct> <fct> <dbl>
1 g1:1  g1       1.
2 g1:2  g1       2.
3 g1:3  g1       3.

代码运行良好,您的所有组的总和均不超过 10。

【讨论】:

  • 我忘了在strsplit 步骤添加tab2$V2:这应该是代码:tab2 &lt;- read.table("dplyrtest.txt",header=FALSE)tab2 &lt;- data.frame(tab2$V1, do.call(rbind, strsplit(as.character(tab2$V1),split=":")),tab2$V2)colnames(tab2) &lt;- c("gene","name","num","count")tab2 %&gt;% group_by(name) %&gt;% filter(sum(as.integer(count)) &gt; 10)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-15
  • 2017-07-29
  • 1970-01-01
  • 2021-12-04
  • 2019-12-28
  • 2017-08-23
  • 2012-10-27
相关资源
最近更新 更多