我的数据集中的每一行都是不同的树。图是指采样区域(其中约有700个),物种是树的种类,其他列是树存在(1)还是不存在(NA)。下面是数据集的最小示例
Plot Species 1983 1988 2003 2008 2013
1 11 1 1 1 1 1
1 11 1 1 1 1 NA
1 21 NA 1 1 1 1
2 11 1 1 1 NA NA
2 34 1 1 1 1 1
3 15 1 1 1 1 NA
3 15 NA 1 1 1 NA
3 11 1 1 1 1 NA
基本上我想知道的是每个地块每年有多少种不同的物种,不包括NA值:
Plot 1983 1988 2003 2008 2013
1 1 2 2 2 2
2 2 2 2 1 1
3 2 2 2 2 0
我目前的策略如下 - 将所有值1更改为其物种编号,以便数据集如下所示
Plot Species 1983 1988 2003 2008 2013
1 11 11 11 11 11 11
1 11 11 11 11 11 NA
1 21 NA 21 21 21 21
2 11 11 11 11 NA NA
2 34 34 34 34 34 34
3 15 15 15 15 15 NA
3 15 NA 15 15 15 NA
3 11 11 11 11 11 NA
然后使用
根据绘图编号拆分数据集split(data, as.factor(data$Plot))
我认为我基本上希望每列的长度能够找出有多少不同的值,但是colSums并不能解释不同的图。当我有一个拆分列表时,我不确定如何使用apply函数。
欢迎任何建议! 感谢
答案 0 :(得分:2)
tidyverse
方法:
library(tidyr)
library(dplyr)
data %>%
gather(Year, Value, na.rm = TRUE, -Plot, -Species) %>%
group_by(Plot, Year) %>%
distinct(Species, .keep_all = TRUE) %>%
count(Plot, Year) %>%
spread(Year, n, fill = 0)
Source: local data frame [3 x 6]
Groups: Plot [3]
Plot `1983` `1988` `2003` `2008` `2013`
* <int> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 1 2 2 2 2
2 2 2 2 2 1 1
3 3 2 2 2 2 0
答案 1 :(得分:2)
一些替代方案与接受的答案计算相同。在基础R中使用split-apply-combine方法,你得到
do.call(rbind, lapply(split(df[-(1:2)] * df$Species, df$lot),
function(x) sapply(x, function(y) length(unique(y[!is.na(y)])))))
X1983 X1988 X2003 X2008 X2013
1 1 2 2 2 2
2 2 2 2 1 1
3 2 2 2 2 0
这需要一个嵌套循环。首先,循环遍历通过拆分批次创建的data.frames列表,然后循环遍历每个年份变量。在这里,带有do.call
的{{1}}会返回一个矩阵。
您可以rbind
使用rbind.data.frame
来返回data.frame
setNames
在这两个中,该批次都包含在行名称中。
然后使用setNames(do.call(rbind.data.frame, lapply(split(df[-(1:2)] * df$Species, df$lot),
function(x) sapply(x,
function(y) length(unique(y[!is.na(y)]))))),
names(df)[-(1:2)])
X1983 X1988 X2003 X2008 X2013
1 1 2 2 2 2
2 2 2 2 1 1
3 2 2 2 2 0
data.table
答案 2 :(得分:1)
我们可以使用library(data.table)
setDT(df1)[, lapply(.SD, function(x) uniqueN(na.omit(x*Species))) , Plot, .SDcols = 3:7]
# Plot 1983 1988 2003 2008 2013
#1: 1 1 2 2 2 2
#2: 2 2 2 2 1 1
#3: 3 2 2 2 2 0
dplyr
使用library(dplyr)
df1 %>%
group_by(Plot) %>%
summarise_each(funs(n_distinct(na.omit(Species * .))), 3:7)
# A tibble: 3 × 6
# Plot `1983` `1988` `2003` `2008` `2013`
# <int> <int> <int> <int> <int> <int>
#1 1 1 2 2 2 2
#2 2 2 2 2 1 1
#3 3 2 2 2 2 0
{{1}}