根据其他列中的值,在数据框中创建具有升序值的新列

时间:2019-02-13 15:59:56

标签: r dataframe

我有一个非常长的数据框(超过30万行),由一个任务的所有主题试验组成,并采用长格式。因此,大约有300行是针对一个主题的连续试验,其次是其他主题。我想做的是创建一个新列,其中包含每个主题的试用编号。

例如:

subject trial_number 101 1 101 2 101 3 102 1 102 2 102 3

我想我应该以某种方式使R从列主题中选择一个主题号,然后创建一个升序列表,然后将其循环到所有主题号上。但是我无法弄清楚如何遍历主题编号,同时又在这些主题的同一列中创建升序列表?创建新列的不同之处在于,我看到的全部都是基于其他列中的计算或值,对我而言,新列中的值不是基于另一列的计算或值。

我还考虑过根据主题编号将数据帧拆分为较小的数据,创建升序列表并再次合并它们?似乎是一种效率很低的方法吗?

我没有用于失败尝试的示例代码,因为我无法弄清楚如何构造它。我在想子集的某种组合?还是我的谷歌搜索技能还没有找到更好的解决方案?

1 个答案:

答案 0 :(得分:0)

使用dplyr

library(dplyr)

dat2 <- dat %>%
  group_by(subject) %>%
  mutate(trial_number = 1:n()) %>%
  ungroup()
dat2
#   subject trial_number
#     <int>        <int>
# 1     101            1
# 2     101            2
# 3     101            3
# 4     102            1
# 5     102            2
# 6     102            3

dat2 <- dat %>%
  group_by(subject) %>%
  mutate(trial_number = row_number()) %>%
  ungroup()
dat2
#   subject trial_number
#     <int>        <int>
# 1     101            1
# 2     101            2
# 3     101            3
# 4     102            1
# 5     102            2
# 6     102            3

data.table

library(data.table)

setDT(dat)

dat[, trial_number := seq_len(.N), by = subject][]
   subject trial_number
1:     101            1
2:     101            2
3:     101            3
4:     102            1
5:     102            2
6:     102            3

或者是rowid中的rowidvdata.table

library(data.table)

setDT(dat)

dat[, trail_number := rowidv(dat, cols = "subject")][]
#    subject trial_number
# 1:     101            1
# 2:     101            2
# 3:     101            3
# 4:     102            1
# 5:     102            2
# 6:     102            3

library(data.table)

setDT(dat)

dat[, trail_number := rowid(dat$subject)][]
#    subject trial_number
# 1:     101            1
# 2:     101            2
# 3:     101            3
# 4:     102            1
# 5:     102            2
# 6:     102            3

或以tapplyunlist为基础的R。

dat2 <- dat
dat2$trial_number <- unlist(tapply(dat$subject, dat$subject, seq_along))
dat2
#   subject trial_number
# 1     101            1
# 2     101            2
# 3     101            3
# 4     102            1
# 5     102            2
# 6     102            3

数据

dat <- read.table(text = "subject
    101
    101
    101
    102
    102
    102 ", header = TRUE)