修改数据框列表中特定列 - R

4
在数据框列表中(mylist<-list(iris, mtcars, ToothGrowth)),我该如何仅更改列表中特定列的内容?
例如,我有一个字符向量(test),其中包含列名"Petal.Width""drat"。我该如何将这些名称与我的数据框列表中的列名匹配,并应用类似于log(x + 1)的操作?
到目前为止,我已经能够单独获取所需列,但我不知道如何保持整个数据框列表并仅更改几列。谢谢
3个回答

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

太棒了!非常感谢。 - J.Con

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接