更改数据框列表中的特定列 - R.

时间:2018-04-12 01:06:22

标签: r list dataframe

在数据框列表中:(mylist<-list(iris, mtcars, ToothGrowth)),如何仅对列表中的特定列进行更改?

例如,我有一个字符向量(test),它给出了列名"Petal.Width""drat"。如何将这些名称与我的数据框列表中的列名匹配,并应用log(x + 1)

之类的内容

到目前为止,我能够获得所需的列out on their own,但我不确定如何将整个数据框列表保持在一起,只是改变了几列。谢谢

3 个答案:

答案 0 :(得分:2)

我首先在您的示例log(x + 1)中定义您要应用的功能:

myfun <- function(x) {
  log(x + 1)
}

然后使用purrr::map浏览列表,dplyr::mutate_at匹配列名:

library(tidyverse)
mylist %>% 
  map(~mutate_at(.x, vars(one_of(c("Petal.Width", "drat"))), myfun))

请注意,这会发出警告,因为并非所有数据框都包含列。如果警告困扰您,您可以使用matches()

mylist %>% 
  map(~mutate_at(.x, vars(matches("^Petal\\.Width|drat$")), myfun))

答案 1 :(得分:1)

我们可以通过几个步骤来实现这一目标

test <- c("Petal.Width", "drat")

#Calculate the new value only for those specific columns which we need
value_cols <- lapply(mylist, function(x) log(x[names(x) %in% test]))

value_cols包含我们需要更改的列的值。

然后我们使用mapply并从每个列表中选择特定列并更新其值。

mapply(function(x, y) {
  x[names(x) %in% test] <- y
  x }, mylist, value_cols)

其中value_cols

value_cols
#[[1]]
#     Petal.Width
#1   -1.60943791
#2   -1.60943791
#3   -1.60943791
#4   -1.60943791
#5   -1.60943791
#...
#...
#[[2]]
#                    drat
#Mazda RX4           1.360977
#Mazda RX4 Wag       1.360977
#Datsun 710          1.348073
#Hornet 4 Drive      1.124930
#Hornet Sportabout   1.147402
#...
#...
#[[3]]
#data frame with 0 columns and 60 rows

答案 2 :(得分:1)

另一种选择是使用intersect和列名来避免收到警告

library(tidyverse)
out <- mylist %>%
           map(~ .x %>%
                  mutate_at(vars(intersect(names(.), test)), myfun))

数据

mylist<-list(iris, mtcars, ToothGrowth)
myfun <- function(x) {
 log(x + 1)
}

test <- c("Petal.Width", "drat")