【发布时间】:2018-05-03 08:50:20
【问题描述】:
我有一个包含字符和数字数据的数据框。我想使用 dplyr 创建按时间点和试验分组的摘要,生成以下内容:
- 平均
- 标准差
- 变化
-
时间点之间的比率
(等等)
我觉得所有这些都可以在 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),"%"))
但我仍然坚持“如何”调用管道内的特定单元格,或者使用哪些其他工具/包来计算同一列中单元格之间的增量或比率。
提前致谢
【问题讨论】: