【问题标题】:Joining columns with similar names in the same data frame [duplicate]在同一数据框中连接具有相似名称的列[重复]
【发布时间】:2019-08-12 12:09:06
【问题描述】:

我正在处理几个物种的植物覆盖数据,其中一些具有相同的属。数据集的每一列是一个物种,每一行是一个采样点。我只需要属级别的覆盖数据,我想对同一属内这些物种的列求和

我有类似的东西,但种类更多:

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))

我的主要问题是我要加入很多不同的属。我曾经考虑过转置数据框并对行求和,我以前做过,但我觉得必须有更好的方法。

【问题讨论】:

  • sapply(split.default(df, sub("\\..*", "", names(df))), rowSums)

标签: r


【解决方案1】:

基于 R 的一个想法是拆分 coplumn 名称并使用 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

【讨论】:

  • 谢谢,这个效果最好。问题是我必须将属保存在列中,将站点保存在行中,因为这是社区生态分析功能承认的唯一格式。
【解决方案2】:

总的来说,我确实认为按照您所说的那样转置您的数据更有意义。这将帮助您利用 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)

【讨论】:

    【解决方案3】:

    考虑将数据从宽变长(几乎所有分析方法中的首选格式),然后按时间段清理 genusspecies 字段的列。从那里运行所需的总和聚合。

    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
    

    Rextester demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-20
      • 1970-01-01
      • 2019-06-24
      • 1970-01-01
      • 2019-12-27
      • 2018-06-20
      • 1970-01-01
      • 2018-09-01
      相关资源
      最近更新 更多