使用mutate创建新列

时间:2018-10-11 07:41:08

标签: r dplyr mutate

我可以找出问题的解决方案,但不是很理想,因此我的解决方案不适用于大df。让我解释。

我有一个大数据框,我需要通过减去另外两个来创建新列。让我向您展示一个简单的df。

A<-rnorm(10)
B<-rnorm(10)
C<-rnorm(10)
D<-rnorm(10)
E<-rnorm(10)
F<-rnorm(10)
df1<-data_frame(A,B,C,D,E,F) 
# A tibble: 10 x 6
        A          B          C          D          E           F
    <dbl>      <dbl>      <dbl>      <dbl>      <dbl>       <dbl>
 1 -2.8750025  0.4685855  2.4435767  1.6999761 -1.3848386 -0.58992249
 2  0.2551404  1.8555876  0.8365116 -1.6151186 -1.7754623  0.04423463
 3  0.7740396 -1.0756147  0.6830024 -2.3879337 -1.3165875 -1.36646493
 4  0.2059932  0.9322016  1.2483196 -0.1787840  0.3546773 -0.12874831
 5 -0.4561725 -0.1464692 -0.7112905  0.2791592  0.5835127  0.16493237
 6  1.2401795 -1.1422917 -0.6189480 -1.4975416  0.5653565 -1.32575021
 7 -1.6173618  0.2283430  0.6154920  0.6082847  0.0273447  0.16771783
 8  0.3340799 -0.5096500 -0.5270123 -0.2814217 -2.3732234  0.27972188
 9 -0.4841361  0.1651265  0.0296500  0.4324903 -0.3895971 -2.90426195
10 -2.7106357  0.5496335  0.3081533 -0.3083264 -0.1341055 -0.17927807

我需要(i)减去相距近的两列:D-A,E-B,F-C,而(ii)根据初始变量名称的名称为新列命名。

我就是这样做的,而且有效:

df2<-df1 %>% 
  transmute (!!paste0("diff","D","A") := D-A,
          !!paste0("diff","E","B") := E-B,
          !!paste0("diff","F","C") := F-C)


# A tibble: 10 x 3
   diffDA     diffEB     diffFC
    <dbl>      <dbl>      <dbl>
 1  4.5749785 -1.8534241 -3.0334991
 2 -1.8702591 -3.6310500 -0.7922769
 3 -3.1619734 -0.2409728 -2.0494674
 4 -0.3847772 -0.5775242 -1.3770679
 5  0.7353317  0.7299819  0.8762229
 6 -2.7377211  1.7076482 -0.7068022
 7  2.2256465 -0.2009983 -0.4477741
 8 -0.6155016 -1.8635734  0.8067342
 9  0.9166264 -0.5547236 -2.9339120
10  2.4023093 -0.6837390 -0.4874314

但是,我有很多专栏,我想找到一种使代码更简单的方法。我尝试了很多事情(例如使用mutate_all,mutate_at或add_columns),但没有任何效果...

3 个答案:

答案 0 :(得分:0)

您可以将数据框分为两部分,然后做

vendor

答案 1 :(得分:0)

请注意,其中带有短划线的列名是不正确的,因此不建议使用。

result = df1[4:6] - df1[1:3]
names(result) = paste(names(df1)[4:6], names(df1)[1:3], sep = "-")
result
#            D-A         E-B        F-C
# 1   0.12459065  0.05855622  0.6134559
# 2  -2.65583389  0.26425762  0.8344115
# 3  -1.48761765 -3.13999402  1.3008065
# 4  -4.37469763  1.37551178  1.3405191
# 5   1.01657135 -0.90690359  1.5848562
# 6  -0.34050959 -0.57687686 -0.3794937
# 7   0.85233808  0.57911293 -0.8896393
# 8   0.01931559  0.91385740  3.2685647
# 9  -0.62012982 -2.34166712 -0.4001903
# 10 -2.21764146  0.05927664  0.3965072

答案 2 :(得分:0)

好的,这是一种适用于数据集整个宽度的方法。

df1 <- tibble(A = rnorm(10),
        B = rnorm(10),
        C = rnorm(10),
        D = rnorm(10),
        E = rnorm(10),
        F = rnorm(10),
        G = rnorm(10),
        H = rnorm(10),
        I = rnorm(10))

ct <- 1:ncol(df1)

diff_tbl <- tibble(testcol = rnorm(10)) 

for (i in ct) {

  new_tbl <- tibble(col = df1[[i+3]] - df1[[i]])
  names(new_tbl)[1] <- paste('diff',colnames(df1[i+3]),colnames(df1[i]),sep='')

  diff_tbl <- bind_cols(diff_tbl,new_tbl)

}

diff_tbl <- diff_tbl %>%
  select(-testcol)

df1 <- bind_cols(df1,diff_tbl)

基本上,您正在做的是创建第二个虚拟小节来计算差异,迭代可能的差异(即三列的间隙),然后将它们组装为单个小节,然后将这些列绑定到原始小节。如您所见,我将df1扩展了三个额外的列,整个过程看起来很吸引人。

很可能有一种更优雅的方法可以做到这一点,但是这种方法肯定有效。我不得不创建一个带有虚拟列的diff_tbl,然后在最终的bind_cols()调用之前将其删除,这是一件有点尴尬的事情,但是我认为这并不是一件大事。