我不知道如何在for循环中将动态变量切割成组。
df
是包含clm_april
- clm_sept
变量double
的数据框。另外,我想为新列添加不同的名称。
每个月不同的群组如下所示:
> groups_april
[1] "0" "500" "1000" "1500" "2000" "3500"
[7] "4500" "5000" "9500" "2000000"
以下不起作用:
vector <- c("april", "may", "june", "july", "aug", "sept")
for (i in vector) {
varname <- paste0("clm_", i)
df <- df %>%
mutate_(.dots =
cut(list(varname),
breaks = groups[i],
include.lowest = T,
dig.lab = 10))
}
我也尝试过:
for (i in vector) {
varname <- paste0("clm_", i)
df <- df %>%
mutate_(.dots = interp(~cut(list(varname),
breaks = groups[i],
include.lowest = T,
dig.lab = 10, varname=as.name(varname))))
}
R抛出以下错误:
Error in mutate_impl(.data, dots) :
Evaluation error: 'x' must be numeric.
你能帮我解决这个问题吗?
编辑:
# A tibble: 10 x 6
clm_april clm_may clm_june clm_july clm_aug clm_sept
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 0 0 0 0 689 0
2 2000 0 1000 1000 1000 0
3 5000 1000 1000 1000 1500 1518
4 1000 1069 1100 1200 2019 2000
5 679 689 9000 10000 36681 2000
6 800 1000 1000 657 1815 2500
答案 0 :(得分:1)
一个选项可能是使用map2_df
包中的purrr
。 map2_df
将允许用于传递实际data.frame
的列式数据。并且同时传递列的名称。自定义函数find_breaks
用于列名称以查找对应的breaks
,然后调用cut
。
Suppose different Groups are defined for each month is defined as:
groups_april <- c("0", "500", "1000", "1500", "2000", "3500", "4500", "5000", "9500", "2000000")
groups_may <- c("0", "500", "1000", "1500", "2000", "3500", "4500", "5000", "9500", "1000000")
groups_june <- c("0", "500", "1000", "1500", "2000", "3500", "4500", "5000", "20000", "2000000")
groups_july <- c("0", "500", "1000", "1500", "2000", "3500", "4500", "7000", "9500", "2000000")
groups_aug <- c("0", "500", "1000", "1500", "2000", "3500", "4500", "6000", "9500", "2000000")
groups_sept <- c("0", "500", "1000", "1500", "2000", "3500", "4500", "5000", "9500", "20000")
#Lets create a data.frame for Groups:
groups_df <- data.frame(groups_april, groups_may, groups_june, groups_july,
groups_aug, groups_sept, stringsAsFactors = FALSE)
# Create a function to find breaks and apply cut
find_breaks <- function(x, y){
#get the corresponding column name
breaks_group_col <- grep(gsub("clm_", "", y), names(groups_df), value = TRUE)
#apply cut using corresponding column from groups_df
cut(x, breaks = groups_df[,breaks_group_col], include.lowest = TRUE, dig.lab = 10)
}
library(purrr)
# Pass df and column names of df to map2.
map2_df(df, grep("clm_*", names(df), value = TRUE), function(.x, .y) find_breaks(.x, .y))
#Result
clm_april clm_may clm_june clm_july clm_aug clm_sept
<fctr> <fctr> <fctr> <fctr> <fctr> <fctr>
1 [0,500] [0,500] [0,500] [0,500] (500,1000] [0,500]
2 (1500,2000] [0,500] (500,1000] (500,1000] (500,1000] [0,500]
3 (4500,5000] (500,1000] (500,1000] (500,1000] (1000,1500] (1500,2000]
4 (500,1000] (1000,1500] (1000,1500] (1000,1500] (2000,3500] (1500,2000]
5 (500,1000] (500,1000] (5000,20000] (9500,2000000] (9500,2000000] (1500,2000]
6 (500,1000] (500,1000] (500,1000] (500,1000] (1500,2000] (2000,3500]
数据强>
df <- read.table(text = "clm_april clm_may clm_june clm_july clm_aug clm_sept
1 0 0 0 0 689 0
2 2000 0 1000 1000 1000 0
3 5000 1000 1000 1000 1500 1518
4 1000 1069 1100 1200 2019 2000
5 679 689 9000 10000 36681 2000
6 800 1000 1000 657 1815 2500", header = T, stringsAsFactors = F)