使用dplyr进行简单变异可以得到错误的结果大小"错误

时间:2017-03-01 19:21:52

标签: r dplyr

我的数据表df有一个subject列(例如" SubjectA"," SubjectB",...)。每个主题都回答了很多问题,表格是长格式的,因此每个主题都有很多行。主题栏是一个因素。我想创建一个新列 - 称之为subject.id - 这只是subject的数字版本。因此对于" SubjectA"的所有行,它将是1;对于" SubjectB"的所有行,它将是2;等

我知道使用dplyr执行此操作的简单方法是致电df %>% mutate(subject.id = as.numeric(subject))。但我试图这样做:

subj.list <- unique(as.character(df$subject))
df %>% mutate(subject.id = which(as.character(subject) == subj.list))

我收到了这个错误:

Error: wrong result size (12), expected 72 or 1

为什么会这样?我对解决这个问题的其他方法不感兴趣。相反,我担心我无法理解这个错误反映了对dplyrmutate的深刻误解。我的理解是这个调用应该在概念上等同于:

df$subject.id <- NULL
for (i in 1:nrow(df)) {
   df$subject.id[i] <- which(as.character(df$subject[i]) == subj.list))
}

但后者有效,前者无效。为什么呢?

可重复示例:

df <- InsectSprays %>% rename(subject = spray)
subj.list <- unique(as.character(df$subject))

# this works
df$subject.id <- NULL
for (i in 1:nrow(df)) {
   df$subject.id[i] <- which(as.character(df$subject[i]) == subj.list)
}

# but this doesn't
df %>% mutate(subject.id = which(as.character(subject) == subj.list))

2 个答案:

答案 0 :(得分:2)

问题是运算符和函数是通过mutate以矢量化方式应用的。因此,which应用于as.character(df$subject) == subj.list生成的向量,而不是每行(如循环中)。

使用此处所述的rowwise可解决此问题:https://stackoverflow.com/a/24728107/3772587

所以,这将有效:

df %>% 
  rowwise() %>%
  mutate(subject.id = which(as.character(subject) == subj.list))

答案 1 :(得分:0)

由于您的df$subject是一个因素,您可以这样做:

df %>% mutate(subj.id=as.numeric(subject))

或使用左连接方法:

subj.df <- df$subject %>% 
    unique() %>% 
    as_tibble() %>% 
    rownames_to_column(var = 'subj.id')

df %>% left_join(subj.df,by = c("subject"="value"))