【问题标题】:How to generate list/table of all the observations with a given value. In R如何生成具有给定值的所有观察值的列表/表格。在 R 中
【发布时间】:2021-08-04 11:37:22
【问题描述】:

我有一个大型数据集 (asv_ar2),指示给定物种在给定位置被记录的次数。如下所示:

Specie loc1 loc2 loc3 loc4
sp1 0 1 0 4
sp2 7 3 0 2
sp3 3 1 0 0

我想为每个物种获取一个列表/表格,其中包含找到它的位置(该变量的值不为 0)。比如:

  • sp1 loc2, loc4
  • sp2 loc1, loc2, loc4
  • sp3 loc1, loc2

或相反,在某个位置发现的物种。

我可以使用 dplyr 的过滤功能选择值>0 的行,但只能逐个位置。 a1<-filter(asv_ar2,asv_ar2[,2]>0)[,c(1,2,8)] 我尝试制作一个将它们连接在一起的循环,但它只显示第一个位置

for(i in 2:1156){ locs<-filter(asv_ar2,asv_ar2[,i]>0)[c(1,i)]}

我不知道如何加入所有迭代。或者如果有更好的方法来完成这一切。

有什么建议吗?

谢谢

【问题讨论】:

    标签: r


    【解决方案1】:

    我希望这是你的想法:

    library(dplyr)
    library(tidyr)
    library(purrr)
    
    df %>%
      mutate(data = pmap(df %>% select(!Specie), ~ names(c(...)[c(...) != 0]))) %>%
      unnest_wider(data)
    
    
    # A tibble: 3 x 8
      Specie  loc1  loc2  loc3  loc4 ...1  ...2  ...3 
      <chr>  <int> <int> <int> <int> <chr> <chr> <chr>
    1 sp1        0     1     0     4 loc2  loc4  NA   
    2 sp2        7     3     0     2 loc1  loc2  loc4 
    3 sp3        3     1     0     0 loc1  loc2  NA 
    

    【讨论】:

      【解决方案2】:

      您可以添加一个列名的新列,其中该列的值连续大于 0。

      asv_ar2$locs <- apply(asv_ar2[-1] > 0, 1, function(x) 
                            toString(names(asv_ar2[-1])[x])) 
      
      asv_ar2
      
      #  Specie loc1 loc2 loc3 loc4             locs
      #1    sp1    0    1    0    4       loc2, loc4
      #2    sp2    7    3    0    2 loc1, loc2, loc4
      #3    sp3    3    1    0    0       loc1, loc2
      

      dplyr 中,您可以使用rowwise

      library(dplyr)
      
      asv_ar2 %>%
        rowwise() %>%
        mutate(locs  = toString(names(.[-1])[c_across(starts_with('loc')) > 0]))
      

      【讨论】:

      • 谢谢,这正是我想要的!
      【解决方案3】:

      我们可以在tidyverse 中以更矢量化的方式执行此操作,即不使用rowwise。在这里,我们循环across'loc'列,如果值不为0,则返回列名(cur_column)(默认case_when返回为NA),指定.names以创建新列通过添加后缀或前缀 (_new),然后使用 unite 将这些“_new”列折叠成一个列

      library(dplyr)
      library(tidyr)
      df1 %>% 
         mutate(across(starts_with('loc'), ~ case_when(. != 0 ~ cur_column()), 
           .names = '{.col}_new')) %>% 
         unite(locs, ends_with('new'), sep=", ", na.rm = TRUE)
      #  Specie loc1 loc2 loc3 loc4             locs
      #1    sp1    0    1    0    4       loc2, loc4
      #2    sp2    7    3    0    2 loc1, loc2, loc4
      #3    sp3    3    1    0    0       loc1, loc2
      

      数据

      df1 <- structure(list(Specie = c("sp1", "sp2", "sp3"), loc1 = c(0L, 
      7L, 3L), loc2 = c(1L, 3L, 1L), loc3 = c(0L, 0L, 0L), loc4 = c(4L, 
      2L, 0L)), class = "data.frame", row.names = c(NA, -3L))
      

      【讨论】:

        【解决方案4】:

        你可以这样做:

        apply(df, 1, function(x) paste(x[1], paste(names(which(x[-1] > 0)), collapse = ", ")))
        [1] "sp1 loc2, loc4"       "sp2 loc1, loc2, loc4" "sp3 loc1, loc2"  
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-11-24
          • 1970-01-01
          • 2019-08-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多