使用dplyr在数据框中变换多个列

时间:2016-11-09 16:03:00

标签: r dplyr

我有以下数据框df

  v1 v2 v3 v4
1  1  5  7  4
2  2  6 10  3

我希望获得以下数据框df2乘以列v1 * v3和v2 * v4:

  v1 v2 v3 v4 v1v3 v2v4
1  1  5  7  4    7   20
2  2  6 10  3   20   18

如何使用dplyr执行此操作?使用mutate_each

我需要一个可以推广到大量变量而不仅仅是4(v1到v4)的解决方案。 这是生成示例的代码:

v1 <- c(1, 2)
v2 <- c(5,6)
v3 <- c(7, 10)
v4 <- c(4, 3)
df <- data.frame(v1, v2, v3, v4)
v1v3 <- c(v1 * v3)
v2v4 <- c(v2 * v4)
df2 <- cbind(df, v1v3, v2v4)

4 个答案:

答案 0 :(得分:18)

你真的很亲密。

df2 <- 
    df %>% 
    mutate(v1v3 = v1 * v3,
           v2v4 = v2 * v4)

这么简单的语言,对吧?

有关更多精彩技巧,请参阅here.

编辑: 感谢@Facottons指向此答案的指针:https://stackoverflow.com/a/34377242/5088194,这是解决此问题的 tidy 方法。它使得人们不必在每个新列所需的硬编码中写入一行。虽然它比 Base R 方法更冗长,但逻辑至少更直接透明/可读。值得注意的是,必须至少有一半的行可用于此方法的列。

# prep the product column names (also acting as row numbers)
df <- 
    df %>%
    mutate(prod_grp = paste0("v", row_number(), "v", row_number() + 2)) 

# converting data to tidy format and pairing columns to be multiplied together.
tidy_df <- 
    df %>%
    gather(column, value, -prod_grp) %>% 
    mutate(column = as.numeric(sub("v", "", column)),
           pair = column - 2) %>% 
    mutate(pair = if_else(pair < 1, pair + 2, pair))

# summarize the products for each column
prod_df <- 
    tidy_df %>% 
    group_by(prod_grp, pair) %>% 
    summarize(val = prod(value)) %>% 
    spread(prod_grp, val) %>% 
    mutate(pair = paste0("v", pair, "v", pair + 2)) %>% 
    rename(prod_grp = pair)

# put the original frame and summary frames together
final_df <- 
    df %>% 
    left_join(prod_df) %>% 
    select(-prod_grp)

答案 1 :(得分:3)

我想我找到了一个解决方案:

div.item

结果对任意数量的变量都有效。它只是新变量名称的问题。这是结果:

df %>%
  mutate(n = df[1:(ncol(df)/2)] * df[(1+ncol(df)/2):(ncol(df))]) %>% head()

答案 2 :(得分:2)

只需使用mutate,使用逗号分隔新列mutate(df,"v1v3"=v1*v3,"v2v4"= v2*v4)

答案 3 :(得分:2)

我们可以使用Mammal代替class Mammal(Animal): ... zoo.add(Mammal(...)) print(zoo) base R

等额外的套餐

我们可以使用dplyr同时向量化多个向量的操作

data.table

我们可以将此数据框合并(mapply)到原始数据框。

如果您对n <- ncol(df)/2 mapply(`*`, df[1:n], df[(n + 1):ncol(df)]) # v1 v2 #[1,] 7 20 #[2,] 20 18 解决方案感兴趣,cbind中的等效内容将是tidyverse的变体

purrr