根据不同的后缀循环减去具有相同前缀的列,结尾以

时间:2019-03-15 20:03:16

标签: r loops for-loop mutate

我有一个大型数据集,其组织方式如下

Date.       A_H.   B_H.   C_H.   D_H.   A_L.   B_L.   C_L.   D_L
1/1/18.      4.    6.       7.      6.   3.     2     2.     4
1/2/18       5.    7.       3.      5.   6.     3     1.     4

我想为每个字母添加高-低的列。因此,在此示例中,我想再增加4列,每个字母从H减去相应的L。但是我的真实数据帧大约有150对,因此我希望采用一种非手动的方式来使前缀匹配并基于后缀。

我尝试了许多方法,包括带突变的for循环,映射以及使用子选择和归约的方法。一个是我的数据框

Aa <- names(a) %>%
    sub(“_\\d+$”, “”, .) %>%
    unique 
Aa %>% 
    map(~a %>%
        select(matches(.x))%>%
        reduce(‘-‘)) %>%
        set_names(paste0(“HL_”, Aa)) %>%
    bind_cols(a, .) 

但是我收到错误消息“ matches是一个未使用的参数”

我也尝试

Aa <- map(c(“A”, “B”, “C”, “D”), ~a %>%
                      mutate(!!as.name(paste0(.x, “_HL”)) := !!as.name(paste0(.x, “_H”)) - !!as.name(paste0(.x, “_L”)))) %>%
    reduce(left_join)

但是我收到错误信息!as.name(paste0(.x,“ _L”)):无效的参数类型

我也尝试       Aa <-c(“ A”,“ B”,“ C”,“ D”)

 for(i in 1:length(Aa)){
     Aaa <- a %>% mutate(a, !!as.name(paste0(Aa[i], “_HL”)) := !!as.name(paste0(Aa[i], “_H”)) - !!as.name(paste0(Aa[i], “_L”)))}

但是我得到了“ LHS必须是名称或字符串错误”

关于我要做什么的任何建议?    预先谢谢你!

1 个答案:

答案 0 :(得分:0)

一种tidyverse可能是:

bind_cols(df %>%
 gather(var, val, -matches("(_L)|(Date)")) %>%
 select(Date., var, val),
 df %>%
 gather(var, val, -matches("(_H)|(Date)")) %>%
 select(Date., var, val)) %>%
 mutate(res1 = paste0(var, "_", var1), 
        res2 = val-val1) %>%
 select(Date., res1, res2) %>%
 spread(res1, res2) %>%
 left_join(df, by = c("Date." = "Date."))

    Date. A_H._A_L. B_H._B_L. C_H._C_L. D_H._D_L. A_H. B_H. C_H. D_H. A_L. B_L. C_L. D_L.
1 1/1/18.         1         4         5         2    4    6    7    6    3    2    2    4
2  1/2/18        -1         4         2         1    5    7    3    5    6    3    1    4

首先,它分别将_H_L列从宽格式转换为长格式。在第二步中,将两列按列合并。完成此步骤后,它将通过合并_H_L列的名称来创建新变量的名称,并从_L列中减去_H列。最后,它将具有所需结果的新变量转换为原始的宽格式,然后将其与基于“日期”的原始df合并。

或者:

df %>%
 gather(var, val, -Date.) %>%
 mutate(temp = gsub("_.*$", "", var)) %>%
 arrange(Date., temp) %>%
 group_by(temp = gl(length(var)/2, 2)) %>%
 mutate(res1 = paste(var, collapse = "_"),
        res2 = val - lead(val)) %>%
 na.omit() %>%
 ungroup() %>%
 select(Date., res1, res2) %>%
 spread(res1, res2) %>%
 left_join(df, by = c("Date." = "Date."))

在这种情况下,它首先将数据从宽格式转换为长格式,但不包括“日期”。柱。其次,它从变量名中获取_之前的字符,并根据“日期”排列数据。还有这个。第三,每两行分配一个因子级别和一个分组。第四,它将变量的名称组合在一起并进行减法。最后,它将数据恢复为原始宽格式,并将其与原始df合并。

或者使用基数R,您可以尝试以下操作:

res <- df[, grepl("_H", colnames(df))] - df[, grepl("_L", colnames(df))]

colnames(res) <- paste(colnames(df[, grepl("_H", colnames(df))]),
                       colnames(df[, grepl("_L", colnames(df))]), sep = "_")

cbind(df, res)

    Date. A_H. B_H. C_H. D_H. A_L. B_L. C_L. D_L A_H._A_L. B_H._B_L. C_H._C_L. D_H._D_L
1 1/1/18.    4    6    7    6    3    2    2   4         1         4         5        2
2  1/2/18    5    7    3    5    6    3    1   4        -1         4         2        1

在这里,首先确定包含_H_L的列。其次,它从_L列中减去_H列。第三,它将_H_L列的列名称组合在一起,并将其作为列名称分配给结果。最后,它将结果与旧的df相结合。