Dplyr:循环创建新列

时间:2018-02-27 23:05:57

标签: r dplyr

编辑:我的数据(可重复研究)如下所示。 dplyr将汇总每个win_name类别的值:

inv_name    inv_province    inv_town    nip win_name    value   start   duration    year
CustomerA   łódzkie TownX   1111111111  CompX   233.50  2015-10-23  24  2017
CustomerA   łódzkie TownX   1111111111  CompX   300.5   2015-10-23  24  2017
CustomerA   łódzkie TownX   1111111111  CompX   200.5   2015-10-23  24  2017
CustomerB   łódzkie TownY   2222222222  CompY   200.5   2015-10-25  12  2017
CustomerB   łódzkie TownY   2222222222  CompY   1200.0  2015-10-25  12  2017
CustomerB   łódzkie TownY   2222222222  CompY   320.00  2015-10-25  12  2017

dplyr将汇总这些值,然后传播将使每个win_name类别的汇总扩展到几列,并带有数值。

我想创建新列,其格式化文本对应于包含数字的现有列。创建与包含数字数据的数字列一样多的列。这些列的数量可以从分析变为分析。到目前为止我的代码看起来像:

county_marketshare<-df_monthly_val %>% 
   select(win_name,value,inv_province) %>% 
   group_by(win_name,inv_province)%>% 
   summarise(value=round(sum(value),0))%>% 
   spread(key="win_name", value=value, fill=0) %>%  # teraz muszę stworzyc kolumny sformatowane "finansowo"
   mutate(!!as.symbol(paste0(bestSup[1],"_lbl")):= formatC(!!as.symbol(bestSup[1]),digits = 0, big.mark = " ", format = "f",zero.print = ""),
          !!as.symbol(paste0(bestSup[2],"_lbl")):= formatC(!!as.symbol(bestSup[2]),digits = 0, big.mark = " ", format = "f",zero.print = ""),
          !!as.symbol(paste0(bestSup[3],"_lbl")):= formatC(!!as.symbol(bestSup[3]),digits = 0, big.mark = " ", format = "f",zero.print = "")
          )

有没有办法循环mutate函数,以便创建与现有数字列一样多的列?具有重复代码的相关行是最后三行。每个新格式化的文本列都具有带后缀的现有数字列的名称。 !! as.symbol可以将参数(源列的名称)与_lbl后缀组合在一起。

3 个答案:

答案 0 :(得分:2)

例如,您可以将mutate_at与函数和条件(如

)一起使用
dat %>% 
mutate_at(.vars = c('num_col1','num_col2'), 
.funs = function(x) if(is.numeric(x)) as.character(x))

这将使用字符列替换指定的数字列。您可以根据需要调整函数,即指定列的外观。我们可以通过更好的数据示例为您提供更多帮助。

您也可以只过滤数字列,然后使用mutate_all:

dat %>%Filter(is.numeric,.) %>% mutate_all(funs(as.character)) 

# Filter() is not dplyr, but base R, caveat capital 'F' ! 
# You can also use dat %>%.[sapply(.,is.numeric)], with the same result
# or dplyr::select_if  

...:)

P.S。总是值得引用参考。看看这个华丽的问题: Selecting only numeric columns from a data frame

答案 1 :(得分:2)

请咨询tidyverse documentation

# mutate_if() is particularly useful for transforming variables from
# one type to another

iris %>% as_tibble() %>% mutate_if(is.factor, as.character)

#> # A tibble: 150 x 5
#>    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#>           <dbl>       <dbl>        <dbl>       <dbl> <chr>  
#>  1         5.10        3.50         1.40       0.200 setosa 
#>  2         4.90        3.00         1.40       0.200 setosa 
#>  3         4.70        3.20         1.30       0.200 setosa 
#>  4         4.60        3.10         1.50       0.200 setosa 
#>  5         5.00        3.60         1.40       0.200 setosa 
#>  6         5.40        3.90         1.70       0.400 setosa 
#>  7         4.60        3.40         1.40       0.300 setosa 
#>  8         5.00        3.40         1.50       0.200 setosa 
#>  9         4.40        2.90         1.40       0.200 setosa 
#> 10         4.90        3.10         1.50       0.100 setosa 
#> # ... with 140 more rows

答案 2 :(得分:0)

出乎意料的是,我发现了http://stackoverflow.com/a/47971650/3480717

的提示

我没有在语法

中意识到这一点
  

mtcars%&gt;%mutate_at(columnstolog,funs(log = log(。)))

添加名称部分&#34; log =&#34;在乐趣中会将其附加到新列的名称....在效果中,以下情况就足够了:

 mutate_if(is.numeric, funs(lbl = formatC(.,digits = 0, big.mark = " ", format = "f",zero.print = "")))

这将生成新列,与原始数字列一样多,并且这些新列的名称将足以使用&#34; _lbl&#34;。无需循环或高级语法。非常感谢Thebo和Nettle