在一个df中使用名称创建另一个数据框的相同列副本

时间:2019-07-10 19:46:41

标签: r for-loop dplyr copy

df <- structure(list(Cars = structure(3:1, .Label = c("Ford ", "Mazda", "Merc"), class = "factor"), Model = structure(c(2L, 1L, 3L), .Label = c("c", "e-class", "gt"), class = "factor"), Color = structure(1:3, .Label = c("Black ", "Blue", "Red"), class = "factor")), class = "data.frame", row.names = c(NA, -3L))
argument <- structure(list(NewVar = structure(3:2, .Label = c("", "SKU", "Vehicle"), class = "factor"), Input = structure(2:3, .Label = c("", "Cars", "Model"), class = "factor")), row.names = 1:2, class = "data.frame")
after <- structure(list(Cars = structure(3:1, .Label = c("Ford ", "Mazda", "Merc"), class = "factor"), Model = structure(c(2L, 1L, 3L), .Label = c("c", "e-class", "gt"), class = "factor"), Color = structure(1:3, .Label = c("Black ", "Blue", "Red"), class = "factor"), Vehicle = structure(3:1, .Label = c("Ford ", "Mazda", "Merc"), class = "factor"), SKU = structure(c(2L, 1L, 3L), .Label = c("c", "e-class", "gt"), class = "factor")), class = "data.frame", row.names = c(NA, -3L))
df
#>    Cars   Model  Color
#> 1  Merc e-class Black 
#> 2 Mazda       c   Blue
#> 3 Ford       gt    Red
argument
#>    NewVar Input
#> 1 Vehicle  Cars
#> 2     SKU Model
after
#>    Cars   Model  Color Vehicle     SKU
#> 1  Merc e-class Black     Merc e-class
#> 2 Mazda       c   Blue   Mazda       c
#> 3 Ford       gt    Red   Ford       gt

我正在尝试for遍历各列,并根据“参数” data.frame创建一个副本。这是我尝试过的方法,但实际上没有用。我有df,自变量和dputs之后。本质上,该参数具有一个标题为“ new var”和“ input”的列。 在论点上,我在“ new var”中有“ Vehicle”,在“ Cars”中有“ input”。 这意味着在原始df中,复制“汽车”并将其命名为“车辆”。
List是动态的,因此我尝试根据参数的长度将其保留在for循环中,即,如果我也希望将颜色复制为绘画,请进行更改。

for (i in 1:length(argument$Input) ){
  df %>%   
  mutate( paste0(argument[i,1]) =  !!as.name(argument[i,2])
     }

请注意,argument[i,1]指的是input,因此“变量”是新的列名。 在dplyr中,这会影响df,因此我认为!!as.name将拉出已经存在的变量,即“汽车”已经在df之前。

2 个答案:

答案 0 :(得分:6)

我们可以通过'argument'的'Input'列选择感兴趣的列,然后使用rename_at更改列名。 “参数”数据集列为factor类,在进行更改时将其转换为character

library(dplyr)
df %>%
    mutate_at(vars(as.character(argument$Input)), list(new= ~ .)) %>% 
    rename_at(vars(matches('new')), ~ as.character(argument[[1]]))
#     Cars   Model  Color Vehicle     SKU
#1  Merc e-class Black     Merc e-class
#2 Mazda       c   Blue   Mazda       c
#3 Ford       gt    Red   Ford       gt

如果我们将OP的for循环与:=配合使用,请确保对!!的{​​{1}}上的名称字符串求值(lhs)< / p>

:=

答案 1 :(得分:4)

这是基本的R选项,当您已有字符列名称时,有时可以更轻松地使用它。注意字符的强制性,因为您提供的数据是作为因素给出的。

library(tidyverse)
df <- structure(list(Cars = structure(3:1, .Label = c("Ford ", "Mazda", "Merc"), class = "factor"), Model = structure(c(2L, 1L, 3L), .Label = c("c", "e-class", "gt"), class = "factor"), Color = structure(1:3, .Label = c("Black ", "Blue", "Red"), class = "factor")), class = "data.frame", row.names = c(NA, -3L))
argument <- structure(list(NewVar = structure(3:2, .Label = c("", "SKU", "Vehicle"), class = "factor"), Input = structure(2:3, .Label = c("", "Cars", "Model"), class = "factor")), row.names = 1:2, class = "data.frame")
after <- structure(list(Cars = structure(3:1, .Label = c("Ford ", "Mazda", "Merc"), class = "factor"), Model = structure(c(2L, 1L, 3L), .Label = c("c", "e-class", "gt"), class = "factor"), Color = structure(1:3, .Label = c("Black ", "Blue", "Red"), class = "factor"), Vehicle = structure(3:1, .Label = c("Ford ", "Mazda", "Merc"), class = "factor"), SKU = structure(c(2L, 1L, 3L), .Label = c("c", "e-class", "gt"), class = "factor")), class = "data.frame", row.names = c(NA, -3L))

add_column <- function(df, new_col, existing_col) {
  new_col <- as.character(new_col)
  existing_col <- as.character(existing_col)
  df[[new_col]] <- df[[existing_col]]
  return(df)
}

for (i in 1:nrow(argument)) {
  df <- add_column(df, argument$NewVar[i], argument$Input[i])
}

df
#>    Cars   Model  Color Vehicle     SKU
#> 1  Merc e-class Black     Merc e-class
#> 2 Mazda       c   Blue   Mazda       c
#> 3 Ford       gt    Red   Ford       gt

reprex package(v0.3.0)于2019-07-10创建