在R中的数据框中创建一个具有1-列值总和的新行

发布于 2025-01-27 16:29:28 字数 1206 浏览 2 评论 0原文

我有一个在不同样品中的物种相对丰度(%)的多元数据集。在此数据框架中,我只有最丰富的物种,因此总数不是100%。

我的数据集看起来像这样,但是有更多的物种和样品:

species = c("Species1","Species2","Species3","Species4","Species5","Species6")
Sample1 = c(0.6,7.9,7.1,2.7,4.5,6.4)
Sample2 = c(1.8,0.3,0.9,3.3,1.7,9.8)
Sample3 = c(9.2,1,8,2.1,8,2.2)
Sample4 = c(6.1,1.3,9,5.3,5.5,6.2)

df = data.frame(species, Sample1, Sample2, Sample3, Sample4)
df

   species Sample1 Sample2 Sample3 Sample4
1 Species1     0.6     1.8     9.2     6.1
2 Species2     7.9     0.3     1.0     1.3
3 Species3     7.1     0.9     8.0     9.0
4 Species4     2.7     3.3     2.1     5.3
5 Species5     4.5     1.7     8.0     5.5
6 Species6     6.4     9.8     2.2     6.2

但是我想制作一个堆叠的条图,我还拥有变量的“其他”,代表了所有最稀有物种的百分比覆盖率,以> 100-计算。列的总和

我想要的结果是:

   species Sample1 Sample2 Sample3 Sample4
1 Species1     0.6     1.8     9.2     6.1
2 Species2     7.9     0.3     1.0     1.3
3 Species3     7.1     0.9     8.0     9.0
4 Species4     2.7     3.3     2.1     5.3
5 Species5     4.5     1.7     8.0     5.5
6 Species6     6.4     9.8     2.2     6.2
7   Others    70.8    82.2    69.5    66.6

我该怎么做?我一直在搜索数小时,但找不到解决方案。

I have a multivariate dataset of species relative abundance (%) in different samples. In this data frame I only have the most abundant species, so the total is not 100%.

My dataset looks like this but with much more species and samples:

species = c("Species1","Species2","Species3","Species4","Species5","Species6")
Sample1 = c(0.6,7.9,7.1,2.7,4.5,6.4)
Sample2 = c(1.8,0.3,0.9,3.3,1.7,9.8)
Sample3 = c(9.2,1,8,2.1,8,2.2)
Sample4 = c(6.1,1.3,9,5.3,5.5,6.2)

df = data.frame(species, Sample1, Sample2, Sample3, Sample4)
df

   species Sample1 Sample2 Sample3 Sample4
1 Species1     0.6     1.8     9.2     6.1
2 Species2     7.9     0.3     1.0     1.3
3 Species3     7.1     0.9     8.0     9.0
4 Species4     2.7     3.3     2.1     5.3
5 Species5     4.5     1.7     8.0     5.5
6 Species6     6.4     9.8     2.2     6.2

But I would like to make a stacked bar plot where I also have the variable "Others" representing the percentage cover of all the rarest species together, calculated as 100 - sum of column

The result I would like is this:

   species Sample1 Sample2 Sample3 Sample4
1 Species1     0.6     1.8     9.2     6.1
2 Species2     7.9     0.3     1.0     1.3
3 Species3     7.1     0.9     8.0     9.0
4 Species4     2.7     3.3     2.1     5.3
5 Species5     4.5     1.7     8.0     5.5
6 Species6     6.4     9.8     2.2     6.2
7   Others    70.8    82.2    69.5    66.6

How can I do? I've been searching for hours but I couldn't find a solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夜访吸血鬼 2025-02-03 16:29:28

要获取所需的数据,请使用汇总(跨())

bind_rows(
  df,
  df %>% summarize(across(starts_with("Sample"),~100-sum(.x))) %>% 
    mutate(species="Others")
)

输出:

   species Sample1 Sample2 Sample3 Sample4
1 Species1     0.6     1.8     9.2     6.1
2 Species2     7.9     0.3     1.0     1.3
3 Species3     7.1     0.9     8.0     9.0
4 Species4     2.7     3.3     2.1     5.3
5 Species5     4.5     1.7     8.0     5.5
6 Species6     6.4     9.8     2.2     6.2
7   Others    70.8    82.2    69.5    66.6

此外,如果要在简单的堆叠条形图中绘制此图,则可以继续使用此操作:

... %>% pivot_longer(cols = -species, names_to="Sample",values_to = "Abundance") %>% 
  ggplot(aes(Sample,Abundance,fill=species)) + 
  geom_col() + 
  labs(fill="", y="Relative Abundance")+
  theme(legend.position = "bottom")

To get the data you need, use summarize(across())

bind_rows(
  df,
  df %>% summarize(across(starts_with("Sample"),~100-sum(.x))) %>% 
    mutate(species="Others")
)

Output:

   species Sample1 Sample2 Sample3 Sample4
1 Species1     0.6     1.8     9.2     6.1
2 Species2     7.9     0.3     1.0     1.3
3 Species3     7.1     0.9     8.0     9.0
4 Species4     2.7     3.3     2.1     5.3
5 Species5     4.5     1.7     8.0     5.5
6 Species6     6.4     9.8     2.2     6.2
7   Others    70.8    82.2    69.5    66.6

Furthermore, if you want to plot this in a simple stacked bar chart, you can continue the pipepline with this:

... %>% pivot_longer(cols = -species, names_to="Sample",values_to = "Abundance") %>% 
  ggplot(aes(Sample,Abundance,fill=species)) + 
  geom_col() + 
  labs(fill="", y="Relative Abundance")+
  theme(legend.position = "bottom")

relative_abundance

雪若未夕 2025-02-03 16:29:28

btw的主要区别和另一个答案是使用data.table

library(data.table)
library(ggplot2)
library(RColorBrewer)
#
setDT(df)
result <- rbind(df, df[, c(species='Others', lapply(.SD, \(x) 100-sum(x))), .SDcols=-1])
result
##     species Sample1 Sample2 Sample3 Sample4
## 1: Species1     0.6     1.8     9.2     6.1
## 2: Species2     7.9     0.3     1.0     1.3
## 3: Species3     7.1     0.9     8.0     9.0
## 4: Species4     2.7     3.3     2.1     5.3
## 5: Species5     4.5     1.7     8.0     5.5
## 6: Species6     6.4     9.8     2.2     6.2
## 7:   Others    70.8    82.2    69.5    66.6

.sdcols = -1表示使用所有列,但第一个列。

#   melt for use in ggplot
#   reorder factors to put "Others" at the top.
#
gg.dt <- melt(result, id='species')[
  , species:=factor(species, levels=c('Others', setdiff(unique(species), 'Others')))]
##
#   use Brewer palette, with grey80 for "Others"
#
ggplot(gg.dt, aes(x=variable, y=value, fill=species))+
  geom_bar(stat='identity', color='grey80')+
  scale_fill_manual(values = c('grey80', brewer.pal(6, 'Spectral')))+
  labs(x=NULL, y='Relative Abundance')

The main difference btw this and the other answer is the use of data.table:

library(data.table)
library(ggplot2)
library(RColorBrewer)
#
setDT(df)
result <- rbind(df, df[, c(species='Others', lapply(.SD, \(x) 100-sum(x))), .SDcols=-1])
result
##     species Sample1 Sample2 Sample3 Sample4
## 1: Species1     0.6     1.8     9.2     6.1
## 2: Species2     7.9     0.3     1.0     1.3
## 3: Species3     7.1     0.9     8.0     9.0
## 4: Species4     2.7     3.3     2.1     5.3
## 5: Species5     4.5     1.7     8.0     5.5
## 6: Species6     6.4     9.8     2.2     6.2
## 7:   Others    70.8    82.2    69.5    66.6

.SDcols = -1 means use all columns but the first one.

#   melt for use in ggplot
#   reorder factors to put "Others" at the top.
#
gg.dt <- melt(result, id='species')[
  , species:=factor(species, levels=c('Others', setdiff(unique(species), 'Others')))]
##
#   use Brewer palette, with grey80 for "Others"
#
ggplot(gg.dt, aes(x=variable, y=value, fill=species))+
  geom_bar(stat='identity', color='grey80')+
  scale_fill_manual(values = c('grey80', brewer.pal(6, 'Spectral')))+
  labs(x=NULL, y='Relative Abundance')

enter image description here

段念尘 2025-02-03 16:29:28

另一个可能的解决方案,基于dplyrcolsums

library(dplyr)

df %>% 
  bind_rows(data.frame(species = "Others", t(100 - colSums(.[-1]))))

#>    species Sample1 Sample2 Sample3 Sample4
#> 1 Species1     0.6     1.8     9.2     6.1
#> 2 Species2     7.9     0.3     1.0     1.3
#> 3 Species3     7.1     0.9     8.0     9.0
#> 4 Species4     2.7     3.3     2.1     5.3
#> 5 Species5     4.5     1.7     8.0     5.5
#> 6 Species6     6.4     9.8     2.2     6.2
#> 7   Others    70.8    82.2    69.5    66.6

Another possible solution, based on dplyr and colSums:

library(dplyr)

df %>% 
  bind_rows(data.frame(species = "Others", t(100 - colSums(.[-1]))))

#>    species Sample1 Sample2 Sample3 Sample4
#> 1 Species1     0.6     1.8     9.2     6.1
#> 2 Species2     7.9     0.3     1.0     1.3
#> 3 Species3     7.1     0.9     8.0     9.0
#> 4 Species4     2.7     3.3     2.1     5.3
#> 5 Species5     4.5     1.7     8.0     5.5
#> 6 Species6     6.4     9.8     2.2     6.2
#> 7   Others    70.8    82.2    69.5    66.6
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文