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

7y4bm7vi  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(50)

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

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

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

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


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

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


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

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

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

library(reshape2)
library(dplyr)
Ndata <- reshape2::melt(normOD ,  id.vars = 'Time', variable.name = 'Well')
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%。
我再次通过制作一个具有相应值的向量来将其像这样除以:

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


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

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

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

dwthyt8l

dwthyt8l1#

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

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

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

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


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

相关问题