【问题标题】:Using dplyr to create new dataframe depending on thresholds使用 dplyr 根据阈值创建新的数据帧
【发布时间】:2020-05-04 15:22:35
【问题描述】:
   Groups Names COL1  COL2  COL3        COL4
1      G1   SP1    1 0.400 0.500   Sequence1
2      G1   SP1    1 0.004 0.005   Sequence2
3      G1   SP1    0 0.004 0.005   Sequence3
4      G1   SP2    0 0.400 0.005 Sequence123
5      G1   SP2    0 0.004 0.500  Sequence14
6      G1   SP3    0 0.005 0.006  Sequence15
7      G1   SP5    1 0.400 0.006  Sequence16
8      G1   SP6    1 0.008 0.002  Sequence20
10     G2   Sp1    0 0.004 0.005  Sequence17
11     G2   SP1    0 0.050 0.600  Sequence18
12     G2   SP1    0 0.400 0.600   Sequence3
13     G2   SP2    0 0.004 0.005  Sequence22
14     G2   SP2    0 0.004 0.005  Sequence23
15     G2   SP5    0 0.004 0.005  Sequence16
16     G2   SP6    0 0.003 0.002  Sequence21
17     G2   SP7    0 0.560 0.760  Sequence67

这里是dput

dput(test_df)
structure(list(Groups = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("G1", "G2"), class = "factor"), 
    Names = structure(c(2L, 2L, 2L, 3L, 3L, 4L, 5L, 6L, 1L, 2L, 
    2L, 3L, 3L, 5L, 6L, 7L), .Label = c("Sp1", "SP1", "SP2", 
    "SP3", "SP5", "SP6", "SP7"), class = "factor"), COL1 = c(1L, 
    1L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L
    ), COL2 = c(0.4, 0.004, 0.004, 0.4, 0.004, 0.005, 0.4, 0.008, 
    0.004, 0.05, 0.4, 0.004, 0.004, 0.004, 0.003, 0.56), COL3 = c(0.5, 
    0.005, 0.005, 0.005, 0.5, 0.006, 0.006, 0.002, 0.005, 0.6, 
    0.6, 0.005, 0.005, 0.005, 0.002, 0.76), COL4 = structure(c(1L, 
    8L, 13L, 2L, 3L, 4L, 5L, 9L, 6L, 7L, 13L, 11L, 12L, 5L, 10L, 
    14L), .Label = c("Sequence1", "Sequence123", "Sequence14", 
    "Sequence15", "Sequence16", "Sequence17", "Sequence18", "Sequence2", 
    "Sequence20", "Sequence21", "Sequence22", "Sequence23", "Sequence3", 
    "Sequence67"), class = "factor")), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "10", "11", "12", "13", "14", 
"15", "16", "17"))
and from this dataf

我想获取另一个数据框,例如:

    G1  G2
SP1 A   B
SP2 x   x
SP3 x   NA
SP4 NA  NA
SP5 A   X
SP6 a x
SP7 NA b

这个想法是让每个组添加行中存在的名称并在单元格中添加字母 A、B、X 或 NA,如果我们找到至少一个相同的 COL4 值,大小写将取决于其他组中的物种。

  • Nameany 行具有COL1 >0 并且至少有一个名称与不同组中的相同名称具有相同的COL4 内容时,放置A
  • Nameany 行有一个COL1 >0 并且没有名称与不同组中的相同名称具有相同的COL4 内容时,将放置a
  • Nameany 行具有COL1=0COL2 AND COL3 > 0.05 并且至少有一个名称具有与相同名称相同的COL4 内容时,
  • B 被放置在不同的组中
  • Nameany 行具有COL1=0COL2 AND COL3 > 0.05 并且没有名称与COL4 内容与a 中的相同名称相同时,
  • b 被放置不同的组
  • all 行的Name 有一个COL1=0COL2``OR COL3 > 0.05 AND 时放置X,至少有一个名称与COL4 内容相同不同的组
  • Nameall 行有一个COL1=0COL2 OR COL3 > 0.05 AND 没有名称具有与相同名称相同的COL4 内容时,
  • x 被放置在不同的组中
  • Group 中没有Name 时放置NA

让我们举4个例子:

1) 对于G1-SP1,我们看到row1 有一个COL1 > 0,然后在新的数据框中它将有一个字母Aa。 现在为了知道它是A 还是a,我们必须查看COL4,我们在row12 中看到Sequence3 也存在于G2 中987654375@,所以它将是'A'

2) 对于G2-SP1,我们看到row12 有一个COL2COL3> 0.05,那么它将在新数据框中有一个字母Bb。 它将是B,因为在G1row3 中,Sequence3 也出现在 SP1 的 G2 中。

3) 对于G2-SP2,我们看到没有一行有COL1 >0XCOL2,而COL3> 0.05,那么它将在新数据框中有一个字母Bx。 它将是x,因为其他Groups 中没有其他SP2 具有相同的序列`(Sequence22,Sequence23 或Sequence24)

4) 对于G1-SP6,我们看到row8 有一个COL1 > 0,然后在新的数据框中它将有一个字母Aa。 它将是a,因为在其他Groups 中没有其他SP1 具有相同的序列(Sequence20)

`

为此我尝试过:

Env_table<-as.data.frame(test_df) %>%
  group_by(Groups,Names) %>%
  mutate(Env_variable = replace_na(COL1, "."),
         Env_variable = ifelse(any(COL1 >=1) , "A", Env_variable)) %>%
  mutate(Env_variable = ifelse(all(COL1 ==0 ) && all(COL2 >0.05) && all(COL3 >0.05) , "B", Env_variable)) %>%
  mutate(Env_variable = ifelse(all(COL1 ==0 ) && all(COL2 <0.05) && all(COL3 <0.05) , "X", Env_variable)) %>%
  mutate(Env_variable = ifelse(all(COL1 ==0 ) && all(COL2 <0.05) && all(COL3 >0.05) , "X", Env_variable)) %>%
  mutate(Env_variable = ifelse(all(COL1 ==0 ) && all(COL2 >0.05) && all(COL3 <0.05) , "X", Env_variable)) %>%
  mutate(Env_variable = ifelse(all(COL1 ==0) && all(!is.na(COL1)) && all(COL2 >0.05) && all(COL3 >0.05) , "*", Env_variable))%>%
  slice(1) %>%
  pivot_wider(id_col = Names, names_from = Groups, values_from = Env_variable) %>%
  arrange(as.integer(str_extract(Names, "\\d+")))

Env_variable 是一个空列,用于存储 A、B、X 或 NA 值。

感谢您的帮助

【问题讨论】:

    标签: r dataframe dplyr


    【解决方案1】:

    您的问题不是很清楚,但这里尝试回答:

    test_df %>% 
      group_by(Groups, Names) %>% 
      summarise(
        x=case_when(
          any(COL1>=1, na.rm=TRUE) ~ "A",
          any(COL1==0 & (COL2>0.05 & COL3>0.05), na.rm=TRUE) ~ "B",
          any(COL1==0 & (COL2<0.05 | COL3<0.05), na.rm=TRUE) ~ "X",
          TRUE ~ NA_character_
        )
      ) %>% 
      pivot_wider(names_from = Groups, values_from = x)
    

    这将给出以下输出:

      Names G1    G2   
      <fct> <chr> <chr>
    1 SP1   A     B    
    2 SP2   X     X    
    3 SP3   X     NA   
    4 SP5   A     X    
    5 SP6   A     X    
    6 SP1   NA    X    
    7 SP7   NA    B
    

    【讨论】:

    • @Grendel 我认为我的答案涵盖了您的算法,但您的预期答案不同。为什么 G2-SP1 应该是 B,因为第 9 行的 COL1==1?此外,您的算法对 B 和 X 之间的区别不够清楚。请注意,“但是”不是逻辑术语;-)
    • 对不起,我改变了它。事实上,当 COL1=0 且 COL2 或 COL3 0.05 AND COL3 > 0.05,获得 A 的唯一方法是让 COL1>1。
    • 不,你是对的,应该是 A 我也改了。感谢您的宝贵时间!
    • 我编辑了一些帖子以增加更多的复杂性(这个想法也是添加大写或小写信息(这将取决于我们是否在另一个物种中找到至少一个物种的相同 COL4 值)组)。也许您有一个想法可以将其包含在您的代码中?
    • 这是一个不同的问题,与您的第一个问题无关,应该在另一篇文章中。我应该考虑一下,但现在我不确定你怎么能做到这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-05
    • 1970-01-01
    • 1970-01-01
    • 2021-02-02
    • 2021-12-29
    • 1970-01-01
    相关资源
    最近更新 更多