根据同一数据框的子集在数据框中添加列

时间:2018-12-18 15:56:32

标签: r dataframe

假设我在R中有一个与此数据帧类似的数据帧:

setValue  <- rep(seq(0,20,10), each=3)
readValue <- rep(1:length(setValue))
df        <- data.frame(setValue, readValue)

结果数据如下:

  setValue readValue
1        0         1
2        0         2
3        0         3
4       10         4
5       10         5
6       10         6
7       20         7
8       20         8
9       20         9

我想添加一个新列,其结果基于setValue定义的组。我将median函数用于该示例。

结果将是这样的:

  setValue readValue  median
1        0         1       2
2        0         2       2
3        0         3       2
4       10         4       5
5       10         5       5
6       10         6       5
7       20         7       8
8       20         8       8
9       20         9       8

解决方案

我最能想到的是使用sapply的R-yfied for-loop()。对于每一行,将检索subset中的df,其中该行的当前setValue等于初始数据帧setValue的{​​{1}}。

df

精简计算

为避免分组和每行重复计算中位数,我可以使用df$median <- sapply(1:nrow(df), function(row) { median( subset(df$readValue, df$setValue == df[row,]$setValue) ) }) 预先计算给定setValue的中位数:

aggregate

得到的数据帧的中位数为df_median <- aggregate(. ~ setValue, data=df, FUN=median)

结果:

readValue

并在函数中使用预先计算的中值:

  setValue readValue
1        0         2
2       10         5
3       20         8

问题

有没有更有效的R-ish方法?

2 个答案:

答案 0 :(得分:0)

使用R开头的ave

transform(df, median = ave(readValue, setValue, FUN = median))

或使用dplyr:

library(dplyr)
df %>%
  group_by(setValue) %>%
  mutate(median = median(readValue)) %>%
  ungroup

答案 1 :(得分:0)

一种data.table方式:

library(data.table)

setDT(df)[, median := median(readValue), by = setValue]

输出:

   setValue readValue median
1:        0         1      2
2:        0         2      2
3:        0         3      2
4:       10         4      5
5:       10         5      5
6:       10         6      5
7:       20         7      8
8:       20         8      8
9:       20         9      8