拆分列表中每列不同值的数量
Number of different values per column in a split list
我的数据集中的每一行都是一棵不同的树。 Plot 是指采样区域(其中大约有 700 个),Species 是树的种类,其他列是树是否存在(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 没有考虑到不同的图。当我有一个拆分列表时,我不确定如何使用应用函数。
欢迎提出任何建议!
谢谢
一个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
我们可以用 data.table
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
几个与接受的答案计算相同的备选方案。在 base 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
和 rbind
return 是一个矩阵。
您可以使用 rbind.data.frame
和 setNames
到 return 一个 data.frame
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
library(data.table)
setDT(df)
df[, lapply(.SD, function(x) length(unique((x * Species)[!is.na(x)]))),
.SDcols=X1983:X2013, by=lot]
lot X1983 X1988 X2003 X2008 X2013
1: 1 1 2 2 2 2
2: 2 2 2 2 1 1
3: 3 2 2 2 2 0
我的数据集中的每一行都是一棵不同的树。 Plot 是指采样区域(其中大约有 700 个),Species 是树的种类,其他列是树是否存在(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 没有考虑到不同的图。当我有一个拆分列表时,我不确定如何使用应用函数。
欢迎提出任何建议! 谢谢
一个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
我们可以用 data.table
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
几个与接受的答案计算相同的备选方案。在 base 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
和 rbind
return 是一个矩阵。
您可以使用 rbind.data.frame
和 setNames
到 return 一个 data.frame
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
library(data.table)
setDT(df)
df[, lapply(.SD, function(x) length(unique((x * Species)[!is.na(x)]))),
.SDcols=X1983:X2013, by=lot]
lot X1983 X1988 X2003 X2008 X2013
1: 1 1 2 2 2 2
2: 2 2 2 2 1 1
3: 3 2 2 2 2 0