【问题标题】:Is there a function to divide values from one column to each (!) value from another? In R是否有将值从一列划分到另一列的每个(!)值的功能?在 R 中
【发布时间】:2021-01-17 23:59:03
【问题描述】:

我有一个如下所示的数据框 (df):

   Code  Status Value
1     1 Treated   1.5
2     1 Treated   1.7
3     1 Treated   1.9
4     1 Control   2.1
5     1 Control   2.3
6     1 Control   2.5
7     2 Treated   1.6
8     2 Treated   1.8
9     2 Treated   2.0
10    2 Control   2.4
11    2 Control   2.6
12    2 Control   2.8

这是它的代码:

df <- data.frame(Code = rep(c(1:2), each = 6),
           Status = rep(rep(c("Treated", "Control"), each = 3), 2),
           Value = c(1.5, 1.7, 1.9, 2.1, 2.3, 2.5, 1.6, 1.8, 2.0, 2.4, 2.6, 2.8))

我需要将每个“控制”值的每个“处理”值划分为一个“代码”(1、2 等)。 基本上,我需要它或多或少地像这样工作:

# 1st "Value" in "Code" 1
df$Value[1]/df$Value[4]
df$Value[1]/df$Value[5]
df$Value[1]/df$Value[6]
# 2nd "Value" in "Code" 1
df$Value[2]/df$Value[4]
df$Value[2]/df$Value[5]
df$Value[2]/df$Value[6]

等等...为了做到这一点,我创建了一个 for 循环,如下所示:

for(i in 1:2){
  for(j in 1:3){
 x <- df$Value[df$Code == i & df$Status == "Treated"]
 y <- df$Value[df$Code == i & df$Status == "Control"]
 vector <- x/y[j]
 print(vector)
  }
} 

结果如下所示。

[1] 0.7142857 0.8095238 0.9047619
[1] 0.6521739 0.7391304 0.8260870
[1] 0.60      0.68      0.76
[1] 0.6666667 0.7500000 0.8333333
[1] 0.6153846 0.6923077 0.7692308
[1] 0.5714286 0.6428571 0.7142857

我的问题是我需要对这些结果进行进一步的计算。 但是,当我尝试提取向量以便我可以使用它时,它只包含最后一个计算:

[1] 0.5714286 0.6428571 0.7142857

有没有更好的计算方法?

附:对于上下文:稍后我需要为每个“代码”计算 MFV(成员函数值),但我需要使用“值”中所有计算(除)值的最小值/最大值。

【问题讨论】:

    标签: r


    【解决方案1】:

    让我们分解问题。假设只有一个代码。该问题可以通过以下方式解决:

    df %>%
      filter(Code == 1) %>%  # --> just select one Code for now
      group_by(Status) %>%   # --> For each status
      mutate(Trial = seq_along(Value)) %>% # --> add helper ID to each row
      spread(Status, Value) %>%       # --> convert rows into columns
      expand(Control, Treated) %>%    # --> create all possible combinations
      mutate(ratio = Treated/Control) # --> compute the ratio
    

    一旦我们有了这个,我们只需要能够处理每个代码。我们可以用一个简单的循环来做到这一点,这里我使用的是lapply,但来自purrrmapfor 循环也会这样做。

    
    process <- function(df){
      df %>%
        group_by(Status) %>%
        mutate(Trial = seq_along(Value)) %>%
        spread(Status, Value) %>%
        expand(Control, Treated) %>%
        mutate(ratio = Treated/Control)
    }
    
    df %>% 
      nest(-Code) %>% 
      mutate(data = lapply(data, process)) %>% 
      unnest(data)
    
    

    【讨论】:

      【解决方案2】:

      这是另一种tidyverse 方法。你可以group_by每个Codenest数据。

      然后,对于每个 Code,您可以使用 outer 来给出两个向量(处理和控制)的乘积 - 但是,您可以提供函数 / 来给出比率(除法)。

      unnest 之后,您将有一个名为Ratio 的列,其中包含一个数字矩阵。请注意,您的结果中仍会包含 Code 列,这将是未来计算所必需的。

      library(dplyr)
      library(tidyr)
      library(purrr)
      
      df %>%
        group_by(Code) %>%
        nest() %>%
        mutate(Ratio = map(data, ~outer(.x$Value[.x$Status == "Treated"], .x$Value[.x$Status == "Control"], `/`))) %>%
        unnest(Ratio) 
      

      输出

         Code data             Ratio[,1]  [,2]  [,3]
        <int> <list>               <dbl> <dbl> <dbl>
      1     1 <tibble [6 × 2]>     0.714 0.652 0.6  
      2     1 <tibble [6 × 2]>     0.810 0.739 0.68 
      3     1 <tibble [6 × 2]>     0.905 0.826 0.76 
      4     2 <tibble [6 × 2]>     0.667 0.615 0.571
      5     2 <tibble [6 × 2]>     0.75  0.692 0.643
      6     2 <tibble [6 × 2]>     0.833 0.769 0.714
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-14
        • 1970-01-01
        • 2020-04-26
        • 1970-01-01
        相关资源
        最近更新 更多