【问题标题】:Calling specific cells in the same column (using dplyr?)调用同一列中的特定单元格(使用 dplyr?)
【发布时间】:2018-05-03 08:50:20
【问题描述】:

我有一个包含字符和数字数据的数据框。我想使用 dplyr 创建按时间点和试验分组的摘要,生成以下内容:

  1. 平均
  2. 标准差
  3. 变化
  4. 时间点之间的比率

    (等等)

我觉得所有这些都可以在 dplyr 管道中完成,但我正在努力确定试验中时间点之间的平均值比率。

我完全承认我可能会随身携带锤子寻找钉子,因此请随时推荐使用其他包或功能的解决方案,但理想情况下,我想要简单/直接的代码,以便多个合作者使用.

library(dplyr)

# creating an example DF 
num <- runif(100, 50, 3200)
smpl <- 1:100
df <- data.frame( num, smpl)
df$time <- "time1"
df$time[seq(2,100,2)] <- "time2"
df$trial <- "a"
df$trial[26:50] <- "b"
df$trial[51:75] <- "c"
df$trial[75:100] <- "d"

# using the magic of pipelines to calculate useful things
df1 <- df %>% 
group_by(time, trial) %>% 
summarise(avg = mean(num), 
var = var(num),
stdev = sd(num))

我很想在上面的这个块中包含 [每次试验的平均时间 2/时间 1 的比率],但我不知道如何用“管道内的 time1" vs "time2"。

从这里开始,没有什么能完全达到我的期望......

df1 <- df1[with(df1,order(trial,time)),] 
# this better ressembles my actual DF structure,
# so reordering it will make some of my next attempts to solve this make more sense

我尝试使用“每隔一行”不同的事实(这并不理想,因为每个 df 将有不同的行数,因此我将引入 NA 或者需要不断更改这些 #'s(或编写一个函数来不断改变它们))

tm2 <- data.frame(x=df1$avg[seq(2,4,2)])
tm1 <- data.frame(x=df1$avg[seq(1,3,2)])

至少,这是我希望包含在 df 中的比率,但与 avg & trial 列相关:

tm2/tm1

只要它在所有试验中保持一致,对我来说,这个比率最终出现在“哪个”时间行并不重要(因此,如果一个比率列对于每个“time1”和“value”都有“空白” " 对于每个 "time2",都可以)。

# I added in a separate column to allow 'match' later
tm1$time <- "time1"
tm2$time <- "time1"  # to keep them all 'in row'
df1$avg_tm1 <- tm1$x[match(df1$time, tm1$time)]
df1$avg_tm2 <- tm2$x[match(df1$time, tm2$time)]

但这也无法与“试用”匹配,因为该信息在这个新的 tm1 df 中丢失了;这真的让我觉得这一切都应该在 dplry 第一次完成...... 然后我尝试在 tm1 df 中创建一个具有比率的新列

tm2$ratio <-tm2$x/tm1$x

仅当平均值匹配时才添加比率值

df1$ratio <- tm2$ratio[match(tm2$x, df1$avg)]

这可能有效,但是当我提取平均值时,它会四舍五入,因此数字不完全匹配。我对此也持谨慎态度,因为如果我处理大量数据,两个随机平均值相似到足以错位这些比率的可能性越来越大。

我尝试了其他几个完全失败的方法,所以让我们假设某些方法有效,并将比率作为单独的列输入 df1

然后任何进一步的计算或注释都是直截了当的:

df2 <- df1 %>% 
mutate(ratio = avg_tm2/avg_tm1,
lost = 1- ratio,
word = paste0(round(lost*100),"%"))

但我仍然坚持“如何”调用管道内的特定单元格,或者使用哪些其他工具/包来计算同一列中单元格之间的增量或比率。

提前致谢

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    我们可以按 'trial' 和 mutate 分组来创建 'ratio' 列

    df1 %>% 
       group_by(trial) %>% 
       mutate(ratio = last(avg)/first(avg))
    # A tibble: 8 x 6
    # Groups:   trial [4]
    #  time  trial   avg      var stdev ratio
    #  <chr> <chr> <dbl>    <dbl> <dbl> <dbl>
    #1 time1 a     1815.  715630.  846. 0.795
    #2 time1 b     2012. 1299823. 1140. 0.686
    #3 time1 c     1505.  878168.  937. 1.09 
    #4 time1 d     1387.  902364.  950. 1.17 
    #5 time2 a     1444.  998943.  999. 0.795
    #6 time2 b     1380.  720135.  849. 0.686
    #7 time2 c     1641. 1205778. 1098. 1.09 
    #8 time2 d     1619.  582418.  763. 1.17 
    

    注意:我们使用 set.seed(2) 创建数据集

    【讨论】:

      【解决方案2】:

      制定一个单独的data.frame:

      set.seed(2)
      # your code above to generate df1
      df2 <- select(df1, time, trial, avg) %>%
        spread(time, avg) %>%
        mutate(ratio = time2/time1)
      df2
      # # A tibble: 4 × 4
      #   trial    time1    time2     ratio
      #   <chr>    <dbl>    <dbl>     <dbl>
      # 1     a 1815.203 1443.731 0.7953555
      # 2     b 2012.436 1379.981 0.6857266
      # 3     c 1505.474 1641.439 1.0903135
      # 4     d 1386.876 1619.341 1.1676176
      

      现在您可以将相关列合并到原始框架中:

      left_join(df1, select(df2, trial, ratio), by="trial")
      # Source: local data frame [8 x 6]
      # Groups: time [?]
      #    time trial      avg       var     stdev     ratio
      #   <chr> <chr>    <dbl>     <dbl>     <dbl>     <dbl>
      # 1 time1     a 1815.203  715630.4  845.9494 0.7953555
      # 2 time1     b 2012.436 1299823.3 1140.0979 0.6857266
      # 3 time1     c 1505.474  878168.3  937.1063 1.0903135
      # 4 time1     d 1386.876  902363.7  949.9282 1.1676176
      # 5 time2     a 1443.731  998943.3  999.4715 0.7953555
      # 6 time2     b 1379.981  720134.6  848.6074 0.6857266
      # 7 time2     c 1641.439 1205778.0 1098.0792 1.0903135
      # 8 time2     d 1619.341  582417.5  763.1629 1.1676176
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多