【问题标题】:Manipulating large dataset with dcast使用 dcast 操作大型数据集
【发布时间】:2020-06-01 16:22:59
【问题描述】:

抱歉,如果这是一个重复的问题,但我找不到我正在寻找的具体答案。我有一个数据框,其中包含在给定旅行中捕获的不同物种的数量。下面是一个包含 5 个行程和 4 个物种的简化示例:

trip = c(1,1,1,2,2,3,3,3,3,4,5,5)
species = c("a","b","c","b","d","a","b","c","d","c","c","d")
count = c(5,7,3,1,8,10,1,4,3,1,2,10)

dat = cbind.data.frame(trip, species, count)
dat

> dat
   trip species count
1     1       a     5
2     1       b     7
3     1       c     3
4     2       b     1
5     2       d     8
6     3       a    10
7     3       b     1
8     3       c     4
9     3       d     3
10    4       c     1
11    5       c     2
12    5       d    10

我只对每次旅行的物种 b 的数量感兴趣。所以我想操作这个数据框,所以我最终得到一个看起来像这样的数据框:

trip2 = c(1,2,3,4,5)
species2 = c("b","b","b","b","b")
count2 = c(7,1,1,0,0)

dat2 = cbind.data.frame(trip2, species2, count2)
dat2

> dat2
  trip2 species2 count2
1     1        b      7
2     2        b      1
3     3        b      1
4     4        b      0
5     5        b      0

我想保留所有旅行,包括未观察到物种 b 的旅行。所以我不能只按物种 b 对数据进行子集化。我知道我可以将数据转换为列,然后像这样删除其他物种的列:

library(dplyr)
library(reshape2)
test = dcast(dat, trip ~ species, value.var = "count", fun.aggregate = sum)
test

> test
  trip  a b c  d
1    1  5 7 3  0
2    2  0 1 0  8
3    3 10 1 4  3
4    4  0 0 1  0
5    5  0 0 2 10

但是,我的真实数据集有数百个物种在数千次旅行中被捕获,如果我尝试将这么多物种投射到列 R 中,就会窒息。列太多了。有没有办法在 dcast 中指定我只想投射物种 b?还是有另一种不需要转换数据的方法?谢谢你。

【问题讨论】:

    标签: r dataframe data-manipulation dcast


    【解决方案1】:

    这是一个data.table 方法,我怀疑它对你来说会很快:

    library(data.table)
    setDT(dat)
    result <- dat[,.(species = "b", count = sum(.SD[species == "b",count])),by = trip]
    result
       trip species count
    1:    1       b     7
    2:    2       b     1
    3:    3       b     1
    4:    4       b     0
    5:    5       b     0
    

    【讨论】:

    • 成功了!非常感谢。仍然需要几分钟才能运行,但它运行良好。而这样一个简单的解决方案。 :)
    【解决方案2】:

    我们可以使用tidyverse

    library(dplyr)
    library(tidyr)
    dat  %>%
       filter(species == 'b') %>% 
       group_by(trip, species) %>%
       summarise(count = sum(count)) %>% 
       ungroup %>% 
       complete(trip = unique(dat$trip), fill = list(species = 'b', count = 0))
    # A tibble: 5 x 3
    #   trip species count
    #  <dbl> <chr>   <dbl>
    #1     1 b           7
    #2     2 b           1
    #3     3 b           1
    #4     4 b           0
    #5     5 b           0
    

    【讨论】:

    • 感谢 akrun,很高兴知道也有一个 tidyverse 方法。但是,当我尝试使用我的实际数据时,对于我的物种未被捕获的旅行,结果表有 NA 而不是零。也许是变量类的问题......?
    • @FishMasterB。我完全使用fill 将 NA 更改为 0
    猜你喜欢
    • 1970-01-01
    • 2015-02-18
    • 1970-01-01
    • 1970-01-01
    • 2019-06-26
    • 2014-12-19
    • 2015-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多