R 有没有办法';合并';两列,其中new column的值是具有特定值的原始列的名称,分组?

R 有没有办法';合并';两列,其中new column的值是具有特定值的原始列的名称,分组?,r,dplyr,data.table,tidyverse,R,Dplyr,Data.table,Tidyverse,我有一个数据框(称之为“df”),包含相当数量的变量(数字、逻辑和字符),代表了一个实验,在这个实验中,不同的细胞类型从一种特定的培养基转移到另一种培养基,细胞的活动在特定的时间被量化。第一列和第二列分别保存“源”培养基的名称和细胞移动到的培养基的名称;第三列描述了活动被量化的时间,第四列是细胞类型,第五列是被测量的活动,这就是有趣的地方 我有两个主要问题,第一个问题是,是否有一种“R-esque”方法来获得第六列,其中包含“Activity”中的值相对于前一行中的值的增加/减少(百分比),但是

我有一个数据框(称之为“df”),包含相当数量的变量(数字、逻辑和字符),代表了一个实验,在这个实验中,不同的细胞类型从一种特定的培养基转移到另一种培养基,细胞的活动在特定的时间被量化。第一列和第二列分别保存“源”培养基的名称和细胞移动到的培养基的名称;第三列描述了活动被量化的时间,第四列是细胞类型,第五列是被测量的活动,这就是有趣的地方

我有两个主要问题,第一个问题是,是否有一种“R-esque”方法来获得第六列,其中包含“Activity”中的值相对于前一行中的值的增加/减少(百分比),但是以分组方式(每个组由Cell.Type、Pre.Medium和Time的组合组成),所以每当Time的值为零时,它的值都是NA

假设这是我的数据帧(为了让我的问题更清楚,我对其进行了简化):

我使用group_by和mutate函数,然后使用lag函数来计算上一行和上一行的增加/减少,有更好的方法吗?对于我的具体情况,lag就足够了,但是如果我在每个“组”中有三个以上的时间测量值,并且需要远远落后于它来计算呢在我的方法中,在某一点上,我不得不使用像lag(lag(lag)(lag(lag)(lag)(活动/lag(活动))-1)*100))之类的东西

另一件事是我无法以任何方式弄清楚的,那就是通过将我的列“Primary.Increase”和“Secondary.Increase”转换为一个名为“Increase.Type”的列,将“wide”数据集转换为一个长数据集,其中每个组的值都由“Increase.Type”组成(Cell.Type、Pre.Med和Time的组合),列的名称(Primary.Response或Secondary.Response)中,其中一个成员的值为TRUE。它应该如下所示:

df <- structure(list(Pre.Med = c("Medium1", "Medium1", "Medium1", "Medium2", 
"Medium2", "Medium2", "Medium1", "Medium1", "Medium1", "Medium2", 
"Medium2", "Medium2"), Pos.Med = c("Medium2", "Medium2", "Medium2", 
"Medium1", "Medium1", "Medium1", "Medium2", "Medium2", "Medium2", 
"Medium1", "Medium1", "Medium1"), Time = c(0, 2, 4, 0, 2, 4, 
0, 2, 4, 0, 2, 4), Cell.Type = c("Cell_A", "Cell_A", "Cell_A", 
"Cell_A", "Cell_A", "Cell_A", "Cell_B", "Cell_B", "Cell_B", "Cell_B", 
"Cell_B", "Cell_B"), Activity = c(0.5, 1, 2, 2, 1, 0.5, 0.2, 
0.8, 0.2, 0.2, 0.2, 0.4), Percent.Inc = c(NA, 100, 100, NA, -50, 
-50, NA, 300, -75, NA, 0, 100), Increase.Type = c("Primary.Increase", 
"Primary.Increase", "Primary.Increase", "Primary.Increase", "Primary.Increase", 
"Primary.Increase", "Primary.Increase", "Primary.Increase", "Primary.Increase", 
"Secondary.Increase", "Secondary.Increase", "Secondary.Increase"
)), class = c("spec_tbl_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-12L), spec = structure(list(cols = list(Pre.Med = structure(list(), class = c("collector_character", 
"collector")), Pos.Med = structure(list(), class = c("collector_character", 
"collector")), Time = structure(list(), class = c("collector_double", 
"collector")), Cell.Type = structure(list(), class = c("collector_character", 
"collector")), Activity = structure(list(), class = c("collector_double", 
"collector")), Percent.Inc = structure(list(), class = c("collector_double", 
"collector")), Increase.Type = structure(list(), class = c("collector_character", 
"collector"))), default = structure(list(), class = c("collector_guess", 
"collector")), skip = 1), class = "col_spec"))
首先有没有办法做到这一点?我想是的,但到目前为止我还没能做到:/ 我是一名生物专业的本科生,对R比较陌生,我喜欢你能用它做什么,但我离擅长它还有很长的路要走


非常感谢您的帮助。

我不确定我是否理解第一个问题。 如果您执行以下操作:

library(dplyr)

df %>%
  group_by(Cell.Type, Pre.Medium, Pos.Medium) %>%
  arrange(Time, .by_group = TRUE) %>% # remove if Time is always ascending
  mutate(Percent.Increase = ((Activity / lag(Activity)) - 1) * 100)
增加百分比的计算是矢量化的,
因此,无论活动持续多长时间都无关紧要
(另见我最后的解释)

关于第二个问题, 如果我理解正确的话, 您可以这样做:

df %>%
  group_by(Cell.Type, Pre.Medium, Pos.Medium) %>%
  mutate(Increase.Type = if (any(Secondary.Increase, na.rm = TRUE)) "Secondary.Increase" else "Primary.Increase") %>%
  select(-(Primary.Increase:Secondary.Increase))
# A tibble: 12 x 7
# Groups:   Cell.Type, Pre.Medium, Pos.Medium [4]
   Pre.Medium Pos.Medium  Time Cell.Type Activity Percent.Increase Increase.Type     
   <chr>      <chr>      <dbl> <chr>        <dbl>            <dbl> <chr>             
 1 Medium1    Medium2        0 Cell_A         0.5               NA Primary.Increase  
 2 Medium1    Medium2        2 Cell_A         1                100 Primary.Increase  
 3 Medium1    Medium2        4 Cell_A         2                100 Primary.Increase  
 4 Medium2    Medium1        0 Cell_A         2                 NA Primary.Increase  
 5 Medium2    Medium1        2 Cell_A         1                -50 Primary.Increase  
 6 Medium2    Medium1        4 Cell_A         0.5              -50 Primary.Increase  
 7 Medium1    Medium2        0 Cell_B         0.2               NA Primary.Increase  
 8 Medium1    Medium2        2 Cell_B         0.8              300 Primary.Increase  
 9 Medium1    Medium2        4 Cell_B         0.2              -75 Primary.Increase  
10 Medium2    Medium1        0 Cell_B         0.2               NA Secondary.Increase
11 Medium2    Medium1        2 Cell_B         0.2                0 Secondary.Increase
12 Medium2    Medium1        4 Cell_B         0.4              100 Secondary.Increase
df%>%
分组依据(单元格类型、前培养基、后培养基)%>%
mutate(Increase.Type=if(any(Secondary.Increase,na.rm=TRUE))“Secondary.Increase”else“Primary.Increase”)%>%
选择(-(主要增加:次要增加))
#一个tibble:12x7
#分组:细胞类型、前培养基、后培养基[4]
前中期位置中期单元格。键入活动百分比。增加。键入
1个培养基1个培养基2 0个细胞,0.5 NA初级。增加
2个介质1个介质2个单元1 100个初级。增加
3个培养基1个培养基2个细胞2 100个初级。增加
4个培养基2个培养基1 0个细胞2 NA初级。增加
5个培养基2个培养基1-50个初级细胞。增加
6个培养基2个培养基4个细胞A 0.5-50个初级细胞。增加
7培养基1培养基2 0细胞B 0.2 NA初级。增加
8介质1介质2单元B 0.8 300初级。增加
9中1中2 4单元B 0.2-75初级。增加
10个培养基2个培养基1 0个细胞B 0.2 NA次级。增加
11介质2介质1 2单元B 0.2 0次级。增加
12介质2介质1 4单元B 0.4 100次级。增加
mutate
中的转换可以看到组中的所有值, 因此
any(Secondary.Increase,na.rm=TRUE)
一次接收所有元素, 如果我们只返回1个值,
它将被复制以适应小组规模。

我不确定我是否理解第一个问题。 如果您执行以下操作:

library(dplyr)

df %>%
  group_by(Cell.Type, Pre.Medium, Pos.Medium) %>%
  arrange(Time, .by_group = TRUE) %>% # remove if Time is always ascending
  mutate(Percent.Increase = ((Activity / lag(Activity)) - 1) * 100)
增加百分比的计算是矢量化的,
因此,无论活动持续多长时间都无关紧要
(另见我最后的解释)

关于第二个问题, 如果我理解正确的话, 您可以这样做:

df %>%
  group_by(Cell.Type, Pre.Medium, Pos.Medium) %>%
  mutate(Increase.Type = if (any(Secondary.Increase, na.rm = TRUE)) "Secondary.Increase" else "Primary.Increase") %>%
  select(-(Primary.Increase:Secondary.Increase))
# A tibble: 12 x 7
# Groups:   Cell.Type, Pre.Medium, Pos.Medium [4]
   Pre.Medium Pos.Medium  Time Cell.Type Activity Percent.Increase Increase.Type     
   <chr>      <chr>      <dbl> <chr>        <dbl>            <dbl> <chr>             
 1 Medium1    Medium2        0 Cell_A         0.5               NA Primary.Increase  
 2 Medium1    Medium2        2 Cell_A         1                100 Primary.Increase  
 3 Medium1    Medium2        4 Cell_A         2                100 Primary.Increase  
 4 Medium2    Medium1        0 Cell_A         2                 NA Primary.Increase  
 5 Medium2    Medium1        2 Cell_A         1                -50 Primary.Increase  
 6 Medium2    Medium1        4 Cell_A         0.5              -50 Primary.Increase  
 7 Medium1    Medium2        0 Cell_B         0.2               NA Primary.Increase  
 8 Medium1    Medium2        2 Cell_B         0.8              300 Primary.Increase  
 9 Medium1    Medium2        4 Cell_B         0.2              -75 Primary.Increase  
10 Medium2    Medium1        0 Cell_B         0.2               NA Secondary.Increase
11 Medium2    Medium1        2 Cell_B         0.2                0 Secondary.Increase
12 Medium2    Medium1        4 Cell_B         0.4              100 Secondary.Increase
df%>%
分组依据(单元格类型、前培养基、后培养基)%>%
mutate(Increase.Type=if(any(Secondary.Increase,na.rm=TRUE))“Secondary.Increase”else“Primary.Increase”)%>%
选择(-(主要增加:次要增加))
#一个tibble:12x7
#分组:细胞类型、前培养基、后培养基[4]
前中期位置中期单元格。键入活动百分比。增加。键入
1个培养基1个培养基2 0个细胞,0.5 NA初级。增加
2个介质1个介质2个单元1 100个初级。增加
3个培养基1个培养基2个细胞2 100个初级。增加
4个培养基2个培养基1 0个细胞2 NA初级。增加
5个培养基2个培养基1-50个初级细胞。增加
6个培养基2个培养基4个细胞A 0.5-50个初级细胞。增加
7培养基1培养基2 0细胞B 0.2 NA初级。增加
8介质1介质2单元B 0.8 300 Pri
df %>%
  group_by(Cell.Type, Pre.Medium, Pos.Medium) %>%
  mutate(Increase.Type = if (any(Secondary.Increase, na.rm = TRUE)) "Secondary.Increase" else "Primary.Increase") %>%
  select(-(Primary.Increase:Secondary.Increase))
# A tibble: 12 x 7
# Groups:   Cell.Type, Pre.Medium, Pos.Medium [4]
   Pre.Medium Pos.Medium  Time Cell.Type Activity Percent.Increase Increase.Type     
   <chr>      <chr>      <dbl> <chr>        <dbl>            <dbl> <chr>             
 1 Medium1    Medium2        0 Cell_A         0.5               NA Primary.Increase  
 2 Medium1    Medium2        2 Cell_A         1                100 Primary.Increase  
 3 Medium1    Medium2        4 Cell_A         2                100 Primary.Increase  
 4 Medium2    Medium1        0 Cell_A         2                 NA Primary.Increase  
 5 Medium2    Medium1        2 Cell_A         1                -50 Primary.Increase  
 6 Medium2    Medium1        4 Cell_A         0.5              -50 Primary.Increase  
 7 Medium1    Medium2        0 Cell_B         0.2               NA Primary.Increase  
 8 Medium1    Medium2        2 Cell_B         0.8              300 Primary.Increase  
 9 Medium1    Medium2        4 Cell_B         0.2              -75 Primary.Increase  
10 Medium2    Medium1        0 Cell_B         0.2               NA Secondary.Increase
11 Medium2    Medium1        2 Cell_B         0.2                0 Secondary.Increase
12 Medium2    Medium1        4 Cell_B         0.4              100 Secondary.Increase