假设我有一个看起来像这样的数据框:
fact_code style_serial ss rib button rib_s button_s
1008 style_1018 1 0 0 1 1
1008 style_1018 0 1 0 1 1
1008 style_1018 0 1 0 1 1
1008 style_1018 0 0 1 1 1
1008 style_1003 1 0 1 0 1
1008 style_1003 0 0 1 0 1
1008 style_1003 0 0 0 0 1
1008 style_1003 0 0 0 0 1
1004 style_1197 1 0 0 1 0
1004 style_1197 0 0 0 1 0
1004 style_1197 0 0 0 1 0
1004 style_1197 0 1 0 1 0
关键变量,肋骨和按钮是虚拟变量。它们指示工厂生产的特定服装款式是否具有罗纹或纽扣或两者兼有。然后,我想利用fact_code
和style_serial
分组的这些虚拟变量中的最大值,在这种情况下,我将它们分别命名为rib_s
和button_s
。
变量rib_s
和button_s
的生成如下:
df <- df %>% group_by(fact_code, style_serial) %>% mutate(rib_s = max(rib, na.rm = TRUE))
df <- df %>% group_by(fact_code, style_serial) %>% mutate(button_s = max(button, na.rm = TRUE))
现在假设我有大约20个这样的变量。我想创建一个循环,该循环运行的次数与变量的数量相同,并且每次都针对20个虚拟变量中的每一个执行上述代码。
我已经尝试将这两个变量作为测试:
for (xx in c("rib", "button")){
df <- df %>%
group_by_(fact_code, style_serial) %>%
yy <- paste0(c(xx, "s"), collapse = "_") %>%
mutate_(yy = max(xx, na.rm = TRUE))
}
但是它给了我以下错误信息:
Error in UseMethod("mutate_") :
no applicable method for 'mutate_' applied to an object of class "character"
我也尝试了诸如tapply
和aggregate
之类的基本r函数,但是总是收到一些错误消息。
您有办法解决这个问题吗?
答案 0 :(得分:2)
使用dplyr::mutate_at
可以非常简洁地解决此问题:
library(dplyr)
key <- c("rib", "button")
df %>%
group_by(fact_code, style_serial) %>%
mutate_at(vars(key), funs(max = max(.)))
## A tibble: 12 x 9
## Groups: fact_code, style_serial [3]
# fact_code style_serial ss rib button rib_s button_s rib_max button_max
# <int> <fct> <int> <int> <int> <int> <int> <dbl> <dbl>
# 1 1008 style_1018 1 0 0 1 1 1. 1.
# 2 1008 style_1018 0 1 0 1 1 1. 1.
# 3 1008 style_1018 0 1 0 1 1 1. 1.
# 4 1008 style_1018 0 0 1 1 1 1. 1.
# 5 1008 style_1003 1 0 1 0 1 0. 1.
# 6 1008 style_1003 0 0 1 0 1 0. 1.
# 7 1008 style_1003 0 0 0 0 1 0. 1.
# 8 1008 style_1003 0 0 0 0 1 0. 1.
# 9 1004 style_1197 1 0 0 1 0 1. 0.
#10 1004 style_1197 0 0 0 1 0 1. 0.
#11 1004 style_1197 0 0 0 1 0 1. 0.
#12 1004 style_1197 0 1 0 1 0 1. 0.
这将自动计算key
中给定变量的最大值(每组),并通过将_max
附加到相应的列名来创建新列。请注意,如果您还可以在select
中使用通常的contains
语义(例如matches
,starts_with
,ends_with
,vars(...)
等)不想(或不能)事先定义key
。
df <- read.table(text =
"fact_code style_serial ss rib button rib_s button_s
1008 style_1018 1 0 0 1 1
1008 style_1018 0 1 0 1 1
1008 style_1018 0 1 0 1 1
1008 style_1018 0 0 1 1 1
1008 style_1003 1 0 1 0 1
1008 style_1003 0 0 1 0 1
1008 style_1003 0 0 0 0 1
1008 style_1003 0 0 0 0 1
1004 style_1197 1 0 0 1 0
1004 style_1197 0 0 0 1 0
1004 style_1197 0 0 0 1 0
1004 style_1197 0 1 0 1 0", header = T)
答案 1 :(得分:0)
对不起,我不在电脑旁,所以我无法尝试修复它,但是当您希望数据框很长时,看来您的数据帧确实很宽。您是否考虑过使用collect()将值是1的列的实际名称替换为布尔值0或1的所有列?
我认为正在生成错误,因为您不能一次在单个行上使用mutate。也许如果您尝试先添加一个临时列,然后尝试将其填充到循环中?