按条件从另一列划分一列数据帧

时间:2016-05-18 15:49:54

标签: r dataframe

我有一个包含2列的数据框:

cond  val
1      5
2      18
2      18
2      18
3      30
3      30

我想以这种方式更改val中的值:

   cond  val
    1      5   # 5 = 5/1  (only "1" in cond column)
    2      6   # 6 = 18/3 (there are three "2" in cond column)
    2      6
    2      6
    3      15  # 15 = 30/2  
    3      15

如何实现这一目标?

5 个答案:

答案 0 :(得分:3)

基础R解决方案:

# method 1:
mydf$val <- ave(mydf$val, mydf$cond, FUN = function(x) x = x/length(x))
# method 2:
mydf <- transform(mydf, val = ave(val, cond, FUN = function(x) x = x/length(x)))

给出:

  cond val
1    1   5
2    2   6
3    2   6
4    2   6
5    3  15
6    3  15

答案 1 :(得分:3)

以下是dplyr方式:

library(dplyr)
df %>%
  group_by(cond) %>%
  mutate(val = val / n())

给出了:

#Source: local data frame [6 x 2]
#Groups: cond [3]
#
#   cond   val
#  (int) (dbl)
#1     1     5
#2     2     6
#3     2     6
#4     2     6
#5     3    15
#6     3    15

我们的想法是使用val

cond除以当前组(n())中的观察数量

答案 2 :(得分:2)

这似乎是data.table

的合适情况
library(data.table)
(dt <- data.table(df)[,val := val / .N, by = cond][])
#    cond val
# 1:    1   5
# 2:    2   6
# 3:    2   6
# 4:    2   6
# 5:    3  15
# 6:    3  15 
df <- read.table(
    text = "cond  val
    1      5
    2      18
    2      18
    2      18
    3      30
    3      30",
    header = TRUE,
    colClasses = "numeric"
)

答案 3 :(得分:2)

在基地R

df$result = df$val / ave(df$cond, df$cond, FUN = length)

ave()cond列除以其唯一值,并获取每个子向量的长度,即您要求的分母。

答案 4 :(得分:0)

如果cond是一个ID变量,这是一个基本的R答案:

# get length of repeats
temp <- rle(df$cond)
temp <- data.frame(cond=temp$values, lengths=temp$lengths)

# merge onto data.frame
df <- merge(df, temp, by="cond")
df$valNew <- df$val / df$lengths