基于自身的特定子集的全框架操作(+dumr)

7y4bm7vi  于 2024-01-03  发布在  其他
关注(0)|答案(1)|浏览(178)

我希望能够对所有列或特定列执行简单的运算,例如除法或乘法,方法是基于一个条件(例如另一行上的匹配ID)使用一个或多个列的同一数据框的子集。
我有关于不同处理的酵母培养物的光密度值(OD)的数据,其中每列是不同时间点的光密度值,可以总结为:

  1. DF <- data.frame(Time=c(1,2,3,4,5,6,7),
  2. A1=c(40,50,60,70,80,90,100),
  3. A2=c(40,50,60,70,80,90,100),
  4. A3=c(20,40,50,60,70,80,90),
  5. B1=c(20,40,50,60,70,80,90),
  6. B2=c(10,20,30,40,50,60,70),
  7. B3=c(14,22,37,45,52,65,73),
  8. C1=c(25,30,41,49,64,71,83),
  9. C2=c(24,30,41,50,63,72,80),
  10. C3=c(28,33,47,51,67,72,88))

字符串
我还有另一个数据框,其中包含每列的相关信息:

  1. INFO<- data.frame(Well=c("A1","A2","A3","B1","B2","B3","C1","C2","C3"),
  2. Strain=rep(c("L","M","N"),times=3),
  3. Treatment=rep(c("0X","X","2X"),each=3))


我必须做的一件事是通过对照处理标准化OD值。在这个例子中,它将是“X”。这意味着我必须将每个值(包括对照处理)除以正确时间点和应变的对照处理的相应值。
我解决这个问题的方法是用cbind创建第二个框架,并重复添加治疗列,如下所示:

  1. normingOD<-DF[,5:7]
  2. normingOD<-cbind(normingOD,normingOD,normingOD)
  3. normOD<-DF[-1]/normingOD
  4. normOD$Time<-DF$Time


这应该提取对应于治疗“X”的列,将它们绑定3次,使它们匹配数据集的大小减去第一列,然后将“DF”除以“normingOD”。这应该有效,因为位置应该匹配,对于时间点和菌株。

我认为这是非常无效的,我想看看是否有更好的方法来做到这一点,因为我的真实的数据集有96列和数千个观察值,而控制处理实际上是其中的12列。我如何才能使其更清晰??

后来,我做了一个很长的格式来处理dplyr,像这样:

  1. library(reshape2)
  2. library(dplyr)
  3. Ndata <- reshape2::melt(normOD , id.vars = 'Time', variable.name = 'Well')
  4. DATA<-merge(Ndata,INFO,by="Well")


在这一点上,我还想添加一个新的列,以百分比形式显示生长差异,但与治疗“0X”的值进行比较。这意味着以某种方式告诉R每个 * 值 * 必须乘以100,然后除以对应于相同 * 时间 * 的 * 值 *,但对于 * 治疗 * =“X 0”和相同菌株。作为示例,井==B1,时间==1,处理==X(值==2)和应变==L的值我将其除以井==A1,时间==1,处理==0X和应变==L(值==1)中的值。如果我做得正确,它应该得到给予perc_growth==50,因为它是X 0处理中值的50%。
我再次通过制作一个具有相应值的向量来将其像这样除以:

  1. vector<-DATA[rep(1:7,9),3]
  2. DATA<-cbind(DATA,vector)
  3. DATA<-DATA%>%
  4. mutate(perc_growth=(value*100)/vector)


这将提取一个向量,其中包含“Strain”“L”和“Treatment”“0X”的值,并重复9次以匹配该矩阵的大小,这样我就可以再次将其用作一个列来除以。

是否有一个更简单,更干净的方式来做这件事,在dupiter或类似的?我很可能会在更多的场合这样做,所以我真的想找到一个更好的方式写这些东西的正确方法!!

我感谢你的期待,我道歉,如果出于某种原因,我没有找到一个职位已经回答这个问题。

dwthyt8l

dwthyt8l1#

我认为你尝试从宽到长是一个好主意-我认为你应该先这样做,然后将INFO连接到长数据:

  1. library(dplyr)
  2. library(tidyr)
  3. DF_long = pivot_longer(DF, -1, names_to = "Well") |>
  4. left_join(INFO, by = "Well")
  5. DF_long
  6. # # A tibble: 63 × 5
  7. # Time Well value Strain Treatment
  8. # <dbl> <chr> <dbl> <chr> <chr>
  9. # 1 1 A1 40 L 0X
  10. # 2 1 A2 40 L X
  11. # 3 1 A3 20 L 2X
  12. # 4 1 B1 20 M 0X
  13. # 5 1 B2 10 M X
  14. # 6 1 B3 14 M 2X
  15. # 7 1 C1 25 N 0X
  16. # 8 1 C2 24 N X
  17. # 9 1 C3 28 N 2X
  18. # 10 2 A1 50 L 0X
  19. # # ℹ 53 more rows
  20. # # ℹ Use `print(n = ...)` to see more rows

字符串
我相信这就是你想要的增长计算:

  1. DF_long |>
  2. ## within each group defined by the same Strain and same Time,
  3. ## deivide each value by the value when Treatment == "0X"
  4. mutate(
  5. growth = value / value[Treatment == "0X"],
  6. as_a_percent = scales::percent_format()(growth),
  7. .by = c(Strain, Time)
  8. ) |>
  9. arrange(Strain, Time, Well) |>
  10. print(n = 20)
  11. # # A tibble: 63 × 7
  12. # Time Well value Strain Treatment growth as_a_percent
  13. # <dbl> <chr> <dbl> <chr> <chr> <dbl> <chr>
  14. # 1 1 A1 40 L 0X 1 100%
  15. # 2 1 A2 40 L X 1 100%
  16. # 3 1 A3 20 L 2X 0.5 50%
  17. # 4 2 A1 50 L 0X 1 100%
  18. # 5 2 A2 50 L X 1 100%
  19. # 6 2 A3 40 L 2X 0.8 80%
  20. # 7 3 A1 60 L 0X 1 100%
  21. # 8 3 A2 60 L X 1 100%
  22. # 9 3 A3 50 L 2X 0.833 83%
  23. # 10 4 A1 70 L 0X 1 100%
  24. # 11 4 A2 70 L X 1 100%
  25. # 12 4 A3 60 L 2X 0.857 86%
  26. # 13 5 A1 80 L 0X 1 100%
  27. # 14 5 A2 80 L X 1 100%
  28. # 15 5 A3 70 L 2X 0.875 88%
  29. # 16 6 A1 90 L 0X 1 100%
  30. # 17 6 A2 90 L X 1 100%
  31. # 18 6 A3 80 L 2X 0.889 89%
  32. # 19 7 A1 100 L 0X 1 100%
  33. # 20 7 A2 100 L X 1 100%
  34. # # ℹ 43 more rows
  35. # # ℹ Use `print(n = ...)` to see more rows


在这一点上,我不明白规范计算,但如果你解释它多一点,我可以编辑,以显示如何做到这一点。

展开查看全部

相关问题