【问题标题】:R: Replacing values conditional on another column AND matching variable namesR:替换以另一列和匹配变量名称为条件的值
【发布时间】:2016-10-31 00:49:54
【问题描述】:

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

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

# 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,如果year &gt;= 2014,我想要bar == bar.2014,如果year &lt; 2014,我想要bar == bar.2009。因此,我正在尝试开发一种解决方案,在该解决方案中,我可以循环遍历(或使用矢量化操作)一个变量名称向量(例如names),用于任意数量的变量,我想替换这些值:

# 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

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

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")))}

【问题讨论】:

  • 不要在列名中存储变量;改成长形,你会避免这些卷积。
  • 很遗憾,我必须以这种格式向某人提供数据,因此我无法以长格式向该人提供数据。
  • 这个解决方案可能对你有用stackoverflow.com/a/30271447/3893729
  • @QuestionAnswer 给那个人some reading。您可能仍想整理您的数据以用于中介目的;如果有必要,你可以在最后把它搞砸。
  • MFR cmets 很有帮助,上面的其他 cmets 没有建设性。

标签: r loops dplyr


【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-03
    • 1970-01-01
    • 1970-01-01
    • 2022-11-30
    • 2020-04-05
    • 2020-01-08
    • 1970-01-01
    • 2021-02-22
    相关资源
    最近更新 更多