首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用dplyr变异数据帧中的多列

使用dplyr变异数据帧中的多列
EN

Stack Overflow用户
提问于 2016-11-09 16:03:00
回答 4查看 71K关注 0票数 19

我有以下数据帧df

代码语言:javascript
复制
  v1 v2 v3 v4
1  1  5  7  4
2  2  6 10  3

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

代码语言:javascript
复制
  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)的解决方案。这是生成示例的代码:

代码语言:javascript
复制
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)
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-11-10 04:03:42

你们真的很亲密。

代码语言:javascript
复制
df2 <- 
    df %>% 
    mutate(v1v3 = v1 * v3,
           v2v4 = v2 * v4)

这么简单的语言,对吧?

有关更多精彩技巧,请参见这里。

编辑:由于@Facottons指向这个答案:https://stackoverflow.com/a/34377242/5088194,这里有一个解决这个问题的整洁方法。它避免了一个人不得不在每个新列中写一行硬代码。虽然它比Base方法要详细一些,但逻辑至少更直接地透明/可读性更强。还值得注意的是,要使这种方法工作,必须至少有一半的行是有列的。

代码语言:javascript
复制
# 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)
票数 32
EN

Stack Overflow用户

发布于 2016-11-09 16:47:49

我们可以使用base R而不是使用任何额外的包,如dplyrdata.table

我们可以使用mapply同时将多个向量的运算矢量化。

代码语言:javascript
复制
n <- ncol(df)/2
mapply(`*`, df[1:n], df[(n + 1):ncol(df)])

#     v1 v2
#[1,]  7 20
#[2,] 20 18

我们可以将这个数据合并(cbind)到您的原始数据。

如果您对tidyverse解决方案感兴趣,那么在purrr中等效的是map2的变体。

代码语言:javascript
复制
purrr::map2_df(df[1:n], df[(n + 1):ncol(df)], `*`)

# A tibble: 2 x 2
#     v1    v2
#  <dbl> <dbl>
#1     7    20
#2    20    18
票数 3
EN

Stack Overflow用户

发布于 2016-11-10 12:45:31

我想我找到了解决办法:

代码语言:javascript
复制
df %>%
  mutate(n = df[1:(ncol(df)/2)] * df[(1+ncol(df)/2):(ncol(df))]) %>% head()

结果对于任意数量的变量都是有效的。新变量的名称仍然是一个问题。其结果是:

代码语言:javascript
复制
  v1 v2 v3 v4 n.v1 n.v2
1  1  5  7  4    7   20
2  2  6 10  3   20   18
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40511202

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档