是否有报告数据不同的列的功能?

Is there a function to report columns where data differs?

提问人:MMamone 提问时间:10/25/2023 最后编辑:Gregor ThomasMMamone 更新时间:10/26/2023 访问量:51

问:

我有一个表格,列出了不同地点物种的存在/不存在 (1/0) 数据,以及它们的历史存在/不存在。我希望能够列出“新”物种,即哪些列在新行中存在,哪些列在历史行中存在 0。

site=c(1,1)
sample=c("hist","new")
speciesA=c(0,0)
speciesB=c(1,1)
speciesC=c(0,1)
df=data.frame(site,sample,speciesA,speciesB,speciesC)
df
#   site sample speciesA speciesB speciesC
# 1    1   hist        0        1        0
# 2    1    new        0        1        1

是否有函数可以返回仅列名,在本例中为“speciesC”?

r

评论


答:

1赞 Gregor Thomas 10/25/2023 #1

我可能会将您的数据转入长格式,并将其作为分组操作进行:

library(tidyr)
library(dplyr)
df |>
  pivot_longer(starts_with("species")) |>
  filter(n_distinct(value) > 1, .by = c(site, name))
# # A tibble: 2 × 4
#    site sample name     value
#   <dbl> <chr>  <chr>    <dbl>
# 1     1 hist   speciesC     0
# 2     1 new    speciesC     1

这在检查哪些条件方面提供了很大的灵活性(例如,如果您只想标记更改 where 和 ,那将是一个简单的更改),并且无论输入的列数如何,都会提供很好的常规输出。如果你只是想把物种名称写出来,你可以添加到这个末尾hist = 0new = 1... |> distinct(name)

2赞 r2evans 10/25/2023 #2

基础 R:

subset(df, select = startsWith(names(df), "species")) |>
  sapply(function(z) all(z == 0:1))
# speciesA speciesB speciesC 
#    FALSE    FALSE     TRUE 

您可以使用您喜欢的任何列选择方法,即使只是在这种情况下。df[,-(1:2)] |> sapply(....)

您可以通过以下方式获取真实的条目:which

subset(df, select = startsWith(names(df), "species")) |>
  sapply(function(z) all(z == 0:1)) |> which() |> names()
# [1] "speciesC"

(这确实依赖于行的顺序,即之前。"hist""new"

评论

0赞 MMamone 10/26/2023
谢谢,有没有办法过滤掉“错误”的回答,只查看真实的回答?
0赞 r2evans 10/26/2023
请看我的编辑
1赞 MMamone 10/27/2023
谢谢,我能够让它与它一起工作。
0赞 mapardo 10/26/2023 #3

将pivot_longer与pivot_wider转换相结合的替代解决方案

library(dplyr)
library(tidyr)

df %>% pivot_longer(-c(site,sample),names_to = "specie", values_to = "present") %>% 
  pivot_wider(names_from = "sample",values_from = "present") %>% filter(hist == 0 & new == 1) %>%
  distinct(site,specie)

因此,您可以获得有关物种和地点的信息:

# A tibble: 1 × 2
   site specie  
  <dbl> <chr>   
1     1 speciesC

这种方式对 NA 值或意外值具有鲁棒性

site=c(1,1)
sample=c("hist","new")
speciesA=c(0,0)
speciesB=c(1,1)
speciesC=c(0,NA_integer_)
speciesD=c(0,10)
df=data.frame(site,sample,speciesA,speciesB,speciesC,speciesD)
df
# site sample speciesA speciesB speciesC speciesD
#    1   hist        0        1        0        0
#    1    new        0        1       NA       10