通过逐行应用函数并创建(可能)创建更大的列来转换R数据帧

时间:2019-12-02 16:57:40

标签: r dataframe dplyr

我正在尝试通过将每一行用作函数参数来转换数据帧(小标题),并从中创建一个新列,该列可能大于参数的数量。考虑下面的示例,其中有一些示例观察结果:

library(dplyr)
library(stringi)

observations <- c("110", "11011", "1100010")

df <- tibble(obs = observations) %>%
    transmute(
        Failure = stri_count(obs, fixed = "0"),
        Success = stri_count(obs, fixed = "1")
    )

df是:

# A tibble: 3 x 2
  Failure Success
    <int>  <int>
1       1      2
2       1      4
3       4      3

我想占用每一行并将其用于计算一堆值,并将每个结果向量保存在新列中。例如,我想这样做:

p_values = pgrid <- seq(from = 0, to = 1, length.out = 11)

df %>%
    rowwise() %>%
    transmute(
        p = p_values,
        likelihood = dbinom(Success,
            size = Failure + Success,
            prob = p_values
        )
    )

Error: Column `p` must be length 1 (the group size), not 11

得到类似的东西

# A tibble: 4 x 11
  p_values likelihood_1 likelihood_2 likelihood_3
     <float>  <float>     <float>      <float>
1       0      ...         ...           ...
2       0.1    ...         ...           ...
...     ...    ...         ...           ...
10      0.9    ...         ...           ...
11      1      ...         ...           ...     

3 个答案:

答案 0 :(得分:1)

由于数据不是“整齐”的格式,因此使用tidyverse的方法这种工作流程可能会有些尴尬。

我将从另一个角度出发,从p_values向量开始:

likelihoods <- 
  tibble(p = p_values) %>%
  mutate(likelihood_1 = dbinom(df[1,]$Success,size = df[1,]$Failure + df[1,]$Success,prob = p),
         likelihood_2 = dbinom(df[2,]$Success,size = df[2,]$Failure + df[2,]$Success,prob = p),
         likelihood_3 = dbinom(df[3,]$Success,size = df[3,]$Failure + df[3,]$Success,prob = p))

答案 1 :(得分:1)

问题是0000, 1111, 0001, 0010, 0100, 1000, 1001, 1010, 1100, 0011, 0101, 0110, 1110, 1101, 1011, 0111 transmute期望元素的数量与行数相同(或者如果将其分组,则该组的行数)。在这里,我们执行mutate-基本上是将每行分组,因此期望的rowwise为1,而输出为'p_values'的n()。一种选择是包装lengthlist,然后用unnest整形为“宽”格式(如果需要)

pivot_wider

答案 2 :(得分:1)

为此,我实际上将切换为purrr。函数pmap()将逐行进行迭代。我们使用..1..2分别表示第一输入和第二输入。使用pmap_dfc()将按列绑定结果(dfc =数据框列)。

library(purrr)
library(tibble)

df %>%
  pmap_dfc(~ dbinom(..2, size = ..1 + ..2, prob = p_values)) %>%
  set_names(paste0("likelihood_", seq_along(.))) %>%
  add_column(p_values = p_values, .before = 1)
# A tibble: 11 x 4
   p_values likelihood_1 likelihood_2 likelihood_3
      <dbl>        <dbl>        <dbl>        <dbl>
 1      0          0          0            0      
 2      0.1        0.027      0.00045      0.0230 
 3      0.2        0.096      0.0064       0.115  
 4      0.3        0.189      0.0284       0.227  
 5      0.4        0.288      0.0768       0.290  
 6      0.5        0.375      0.156        0.273  
 7      0.6        0.432      0.259        0.194  
 8      0.7        0.441      0.360        0.0972 
 9      0.8        0.384      0.410        0.0287 
10      0.9        0.243      0.328        0.00255
11      1          0          0            0