R:以另一列为条件替换值并匹配变量名

时间:2016-10-31 00:49:55

标签: r loops dplyr

我的总体目标是从多个变量之一为新变量赋值,特定字符串匹配以另一个变量的值为条件。更具体地说:

我正在尝试向数据框添加许多列,其中每个给定的新列(例如&#39; foo&#39;)采用数据框中已有的两列之一的值,其名称开始使用相同的字符串并以两个后缀中的一个结尾(例如&#39; foo.2009&#39;和&#39; foo.2014&#39;)以另一列的值为条件(例如&#39; year&# 39)。数据框还包含与此操作无关的列,这些列通过缺少后缀来标识(例如&#39; other_example&#39;不要以&#39; .2009&#39;或&#39; .2014&#结尾39;)我创建了一个新列名称的向量。在下面的示例数据中,我想从foo foo.2014分配值year >=2014,如果foo.2009则从year < 2014分配值。

# Original data frame
df <- data.frame( foo.2009 = seq(1,3),
                  foo.2014 = seq(5,7),
                  foo = NA,
                  bar = NA,
                  other_example = seq(20,22),
                  year = c(2014,2009,2014))
print(df)

# The vector of variable names ending in '.####`
names <- c("foo")

# Target data frame
df$foo <- c(5,2,7)
print(df)

在我的真实数据中,我有很多变量(例如bar)类似于foo我需要bar == bar.2014 year >= 2014bar == bar.2009 year < 2014 names 1}}。因此,我正在尝试开发一个解决方案,我可以循环(或使用矢量化操作)变量名称的向量(例如# The vector of variable names ending in `.####` names <- c("foo","bar") # Original data frame df <- data.frame( foo.2009 = seq(1,3), foo.2014 = seq(5,7), bar.2009 = seq(8,10), bar.2014 = rep(5,3), foo = NA, bar = NA, other_example = seq(20,22), year = c(2014,2009,2014)) df # Target data frame df$foo <- c(5,2,7) df$bar <- c(5,9,5) df ),用于任意大量的变量,我想要替换值:

library(dplyr)

for (i in names){
  var09 <- paste0(i, ".2009")
  var14 <- paste0(i, ".2014")
  dplyr::mutate_(df,
                 i = ifelse(df$year < 2010,
                            paste0("df$",i, ".2009"),
                            paste0("df$",i, ".2014")))}

我特别难以在循环中评估包含变量名的多个字符串或使用矢量化方法。下面尝试使用dplyr :: mutate()添加变量然后为它们赋值。下面是与上面相同的数据,但是重新编码的附加变量的示例如下所示。

String[] stateCapsArray = str_data.split(":");
for(int i=0;i<stateCapsArray.length-1;i++) {
    //Skip each other element as we are collecting 2 elements at a time
    if(i%2 == 0) {
        String state = stateCapsArray[i];
        String capital = stateCapsArray[i+1];
        capitals.put(state, capital);
    }
}

1 个答案:

答案 0 :(得分:1)

我们可以遍历base R

中的序列
nm1 <- c("foo\\.\\d+", "bar\\.\\d+")
nm2 <- c("foo", "bar")
for(j in seq_along(nm1)){
  sub1 <- df[grep(nm1[j], names(df))]
  df[[nm2[j]]] <- ifelse(df$year < 2010, sub1[[1]], sub1[[2]])
 }

df
#   foo.2009 foo.2014 bar.2009 bar.2014 foo bar other_example year
#1        1        5        8        5   5   5            20 2014
#2        2        6        9        5   2   9            21 2009
#3        3        7       10        5   7   5            22 2014