【问题标题】:Make a new dataframe of duplicate characters for each level of a subsetted factor为子集因子的每个级别创建一个包含重复字符的新数据框
【发布时间】:2017-05-26 05:14:13
【问题描述】:

我在名为“interact”的列中有一个物种 i 和 j(例如 A_B)之间共享交互的数据框 (df)。交互是从对应的绘图和交互采样的区域记录的。我想在一个区域内的地块之间找到所有 SHARED 交互。因此,对于每个区域子集,输出应返回该区域内地块之间发生的重复交互。数据如下:

df<-

region     plot    interact
 1          104      A_B  
 1          105      B_C
 1          106      A_B
 1          107      C_D
 2          108      B_C
 2          109      B_C
 2          110      E_F
 2          111      B_C
 3          112      A_B
 3          113      A_B

我希望输出是一个数据框,只显示一个区域内的地块之间的共享交互。每个区域的唯一交互将被删除。所以上面例子的输出显示为:

output

 region    interact
  1          A_B
  2          B_C
  3          A_B

我尝试了一个 for 循环

region<-NA
shared.interact<- NA

for (i in 1:length(unique(df$region)) {
region[i] <- unique(df$region)          
shared.interact[i]<- duplicated(df$interact)
}


data.frame(region, shared.interaction)

【问题讨论】:

    标签: r


    【解决方案1】:

    这是一个使用拆分-应用-组合方法的基本 R 方法。

    do.call(rbind, lapply(split(df[c("region", "interact")], df$region),
                          function(x) unique(x[duplicated(x$interact),])))
      region interact
    1      1      A_B
    2      2      B_C
    3      3      A_B
    

    在区域上拆分子集 data.frame,然后应用一个函数,该函数返回一个 data.frame,其中包含对这些区域中的每个区域都有重复的唯一观察集。最后,rbind这些和do.call


    data.table 这将是

    library(data.table)
    setDT(df)[, unique(interact[duplicated(interact)]), by=region]
       region  V1
    1:      1 A_B
    2:      2 B_C
    3:      3 A_B
    

    数据

    df <-
    structure(list(region = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 
    3L), plot = 104:113, interact = structure(c(1L, 2L, 1L, 3L, 2L, 
    2L, 4L, 2L, 1L, 1L), .Label = c("A_B", "B_C", "C_D", "E_F"), class = "factor")), .Names = c("region", 
    "plot", "interact"), class = "data.frame", row.names = c(NA, 
    -10L))
    

    【讨论】:

    • 谢谢。在不到一个小时的时间里,你就帮我完成了一项让我花了一整个上午才试图弄清楚的任务。我感谢您的帮助。 @Imo
    【解决方案2】:

    使用dyplr 你可以这样做:

    library(dplyr)
    
    df %>% 
      group_by(region) %>% 
      count(interact) %>% 
      filter(n > 1)
    #> # A tibble: 3 x 3
    #> # Groups:   region [3]
    #>   region interact     n
    #>    <int>    <chr> <int>
    #> 1      1      A_B     2
    #> 2      2      B_C     3
    #> 3      3      A_B     2
    

    您按region 分组,计算值在interact 中出现的频率,并保留出现多次的值。您可以通过在管道末尾添加 %&gt;% select(-n) 来删除新列。

    【讨论】:

      【解决方案3】:
      library(data.table)
      
      
      df<-read.table(header=TRUE,text={"
      region     plot    interacti
      1          104      A_B  
      1          105      B_C
      1          106      A_B
      1          107      C_D
      2          108      B_C
      2          109      B_C
      2          110      E_F
      2          111      B_C
      3          112      A_B
      3          113      A_B"})
      
      dt <- data.table(dt)
      

      regioninteracti对数据进行排序

      setkey(dt,region,interacti)
      

      仅使用所需的列。搜索重复项,最后搜索unique

      unique(dt[,.(region,interacti)][duplicated(region)&duplicated(interacti),])
      
      #    region interacti
      # 1:      1       A_B
      # 2:      2       B_C
      # 3:      3       A_B
      

      【讨论】:

      • 感谢您抽出宝贵时间解决此问题。您的回答很有帮助,但是由于我的数据是数据框,因此它比其他解决方案多一步。我很欣赏代码的清晰逻辑。谢谢@DJJ
      猜你喜欢
      • 2013-10-29
      • 2021-06-10
      • 1970-01-01
      • 2017-11-26
      • 1970-01-01
      • 1970-01-01
      • 2020-08-04
      • 1970-01-01
      • 2014-02-11
      相关资源
      最近更新 更多