在数据框列表中:(mylist<-list(iris, mtcars, ToothGrowth)
),如何仅对列表中的特定列进行更改?
例如,我有一个字符向量(test
),它给出了列名"Petal.Width"
和"drat"
。如何将这些名称与我的数据框列表中的列名匹配,并应用log(x + 1)
?
到目前为止,我能够获得所需的列out on their own,但我不确定如何将整个数据框列表保持在一起,只是改变了几列。谢谢
答案 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")