4

I have problems with a function of library dplyr. I want to group a dataframe by various values ("group_by"). Some of these values are fix (always the same), and some are introduced through a vector. This vector would have variable dimensions. When the data frame will be grouped, I want to apply the function "mutate".

I have tryed to do it by different ways. The first is copied below, and includes a loop that goes over the vector campToAgregate (where are located the values needed to group the dataframe):

campToAgregate = c("via","nomDem") dadesCom <- dades for(i in 1:length(campToAgregate)){ if(i==1){ dadesCom1 <- dadesCom %>% dplyr::group_by(dadesCom[,which(names(dadesCom) == campToAgregate[i])], dat, add=TRUE) %>% dplyr::mutate(vel1 = round(weighted.mean(vel, longPk, na.rm = TRUE), 0)) dadesCom1 <- dadesCom1[,-(ncol(dadesCom1)-1)] }else{ dadesCom2 <- dadesCom1 %>% dplyr::group_by(dadesCom1[,which(names(dadesCom1) == campToAgregate[i])], add=TRUE) %>% dplyr::mutate(vel1 = round(weighted.mean(vel, longPk, na.rm = TRUE), 0)) } } 

dades is the dataframe, and it contains a lot of values, including the values that are mentioned in the function above: "vel" and "longPk".

When I run this code, the following error appears in the console:

Error in mutate_impl(.data, dots) : not compatible with STRSXP 

And I don't know how to solve it...

I have also tryed to do it by a different way:

for(i in 1:length(campToAgregate)){ if(i==1){ dadesCom <- dadesCom %>% dplyr::group_by(dadesCom[,which(names(dadesCom) == campToAgregate[i])], dat, add=TRUE) }else{ dadesCom <- dadesCom %>% dplyr::group_by(dadesCom1[,which(names(dadesCom1) == campToAgregate[i])], add=TRUE) } } dadesCom <- dadesCom %>% dplyr::mutate(vel = round(weighted.mean(vel, longPk, na.rm = TRUE), 0)) 

But in this case the function group_by doesn't work. The mutate function works, but it's applied to the dataframe without group.

Does anybody know what kind of mistakes I'm doing in the code? Thank you.

1
  • I can't reproduce your example, so I'm guessing with this suggestion. I don't see dat defined anywhere, and you seem to by trying to group by a data frame. group_by expects unquoted variable names. In your case, you don't always know the variables names, and so unquoting them can be a challenge. This is a case where group_by_at is useful, as you can pass a character vector of variable names to the .vars argument and get the same effect. Commented Nov 28, 2017 at 15:04

2 Answers 2

1

I was able to reproduce the error. Testing the code piecemeal, we find that

dadesCom2 <- dadesCom1 %>% dplyr::group_by(dadesCom1[,which(names(dadesCom1) == campToAgregate[i])], add=TRUE) %>% dplyr::mutate(vel1 = round(weighted.mean(vel, longPk, na.rm = TRUE), 0)) 

produces this error

Error in grouped_df_impl(data, unname(vars), drop) : Column dadesCom1[, which(names(dadesCom1) == i)] can't be used as a grouping variable because it's a tbl_df/tbl/data.frame

Simply add

dadesCom1 <- as.data.frame(dadesCom1) 

to the end of your first statement.

I'd also suggest using library(dplyr) and removing your in-line calls

Sign up to request clarification or add additional context in comments.

Comments

1

This can be accomplished using tidy evaluation semantics. Here is an example using mtcars as no sample data was provided:

library(dplyr) ag <- c(quo(cyl), quo(gear)) lapply(ag, function(x) mtcars %>% group_by(!!x) %>% mutate(vel1 = round(weighted.mean(hp, wt, na.rm = TRUE), 0))) 

Depending on the desired output summarise might be a better suited function as it will only display one row for each group

lapply(ag, function(x) mtcars %>% group_by(!!x) %>% summarise(vel1 = round(weighted.mean(hp, wt, na.rm = TRUE), 0))) [[1]] # A tibble: 3 x 2 cyl vel1 <dbl> <dbl> 1 4 83 2 6 122 3 8 209 [[2]] # A tibble: 3 x 2 gear vel1 <dbl> <dbl> 1 3 182 2 4 94 3 5 219 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.