我正在处理几种物种的植物覆盖数据,其中一些具有相同的属。数据集的每一列都是一个物种,每一行都是一个采样点。我只需要属下的覆盖数据,我想对同一属下的那些物种的列求和。
我有类似的东西,但种类更多:
df<-data.frame('Abies.alba'= c(0, 1, 0, 0, 1), 'Acer.opalus'= c(0, 0, 1, 1, 1),
'Acer.campestre'= c(1, 0 , 1, 1, 0), 'Pinus.sylvestris'= c(1, 1, 1, 1, 1),
'Pinus.uncinata'= c(0, 0, 1, 0, 0))
我想有类似的东西:
df2<-data.frame('Abies'= c(0, 1, 0, 0, 1), 'Acer'= c(1, 0, 2, 2, 1),
'Pinus'= c(1, 1, 2, 1, 1))
我的主要问题是我有很多不同的属要加入。我曾考虑过转置数据框并汇总行,这是我以前做过的,但我觉得必须有一种更好的方法。
答案 0 :(得分:2)
通过基数R的想法是拆分共栏名称,并使用grepl
查找相似的名称,即
sapply(unique(gsub('\\..*', '', names(df))), function(i)rowSums(df[grepl(i, names(df))]))
# Abies Acer Pinus
#[1,] 0 1 1
#[2,] 1 0 1
#[3,] 0 2 2
#[4,] 0 2 1
#[5,] 1 1 1
答案 1 :(得分:1)
请考虑将数据的形状从宽变长(在几乎每种分析方法中都是首选格式),然后按时期清除属和物种字段的列。从那里运行所需的总和。
rdf <- reshape(df, varying = list(names(df)), v.names = "value",
times = names(df), timevar="species",
new.row.names = 1:1E6, direction = "long")
rdf$genus <- gsub("\\..*", "", rdf$species)
rdf$species <- gsub(".*\\.", "", rdf$species)
head(rdf)
# species value id genus
# 1 alba 0 1 Abies
# 2 alba 1 2 Abies
# 3 alba 0 3 Abies
# 4 alba 0 4 Abies
# 5 alba 1 5 Abies
# 6 opalus 0 1 Acer
aggdf <- aggregate(value ~ genus, rdf, sum)
aggdf
# genus value
# 1 Abies 2
# 2 Acer 6
# 3 Pinus 6
答案 2 :(得分:1)
总的来说,我确实认为像您所说的那样转置数据更有意义。这将帮助您利用R的矢量化操作,该操作最适合“整洁”的数据(https://cran.r-project.org/web/packages/tidyr/vignettes/tidy-data.html)。这就是我的方法:
library(tidyverse)
df %>%
rowid_to_column() %>%
gather(species, count, 2:6) %>%
mutate(species = str_replace(species, "(?=\\.).+", "")) %>%
group_by(rowid, species) %>%
summarise(count = sum(count))
# which gets you
# A tibble: 15 x 3
# Groups: rowid [5]
rowid species count
<int> <chr> <dbl>
1 1 Abies 0
2 1 Acer 1
3 1 Pinus 1
4 2 Abies 1
5 2 Acer 0
6 2 Pinus 1
7 3 Abies 0
8 3 Acer 2
9 3 Pinus 2
10 4 Abies 0
11 4 Acer 2
12 4 Pinus 1
13 5 Abies 1
14 5 Acer 1
15 5 Pinus 1
如果您真的想在列中输入属信息,则可以添加以下行:
df %>%
rowid_to_column() %>%
gather(species, count, 2:6) %>%
mutate(species = str_replace(species, "(?=\\.).+", "")) %>%
group_by(rowid, species) %>%
summarise(count = sum(count)) %>%
ungroup() %>%
spread(species, count) %>%
select(-rowid)