微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

R适用于列表列表以将相同功能应用于预定义列

如何解决R适用于列表列表以将相同功能应用于预定义列

我有一个列表列表(2个df),并且希望使用lapply对每个df中的预定义列执行相同的功能

我特别想使用DescTools包中的winsorize函数。目前,我知道如何通过指定function(x)命令中的所有单独列来执行此操作,但是,如果我有很多列,这将很繁琐(请参见示例)。

应用该函数后,应返回带有已转换变量的整个列表列表(所有列)。理想情况下,将转换后的变量扩展为“ _w”(例如“ price_w”)或类似名称,以表示这些变量是经过Winsor化的变量。

我的数据如下所示,尽管我只想将该功能应用于预定义的列“价格”和“质量”。

id <- c(1,5,7,9,12)
country <- c("A","A","C","E","E")
price <- c(2.1,4.6,3.7,2.9,1.8)
quality <- c(3.1,5.2,3.3,1.7,0.9)
df1 <- cbind.data.frame(id,country,price,quality)

id <- c(2,3,4,10,14)
country <- c("F","F","Z","X")
price <- c(1.8,3.9)
quality <- c(4.3,2.5,6.9,1.9,0.8)
df2 <- cbind.data.frame(id,quality)

my.list <- list(df1,df2)

cols <- c("price","quality")

这是我到目前为止的内容,由于必要的手动更改,该方法仅适用于少量列:

my.list <- lapply(my.list,function(x) {
  x$price_w <- DescTools::Winsorize(x$price,probs = c(.01,.99),na.rm = TRUE)
  x$quality_w <- DescTools::Winsorize(x$quality,na.rm = TRUE)
  return(x)
})

解决方法

我们可以使用嵌套的lapply将函数应用于每个列表中的多列。

lapply(my.list,function(x) {
  x[paste0(cols,'_w')] <- lapply(x[cols],DescTools::Winsorize)
  x
})

#[[1]]
#  id country price quality price_w quality_w
#1  1       A   2.1     3.1    2.10      3.10
#2  5       A   4.6     5.2    4.42      4.82
#3  7       C   3.7     3.3    3.70      3.30
#4  9       E   2.9     1.7    2.90      1.70
#5 12       E   1.8     0.9    1.86      1.06

#[[2]]
#  id country price quality price_w quality_w
#1  2       F   1.8     4.3    2.02      4.30
#2  3       F   5.2     2.5    5.08      2.50
#3  4       A   2.9     6.9    2.90      6.38
#4 10       Z   4.6     1.9    4.60      1.90
#5 14       X   3.9     0.8    3.90      1.02
,

一个purrrdplyr选项可以是:

map(.x = my.list,~ .x %>%
     mutate(across(all_of(cols),list(w = ~ DescTools::Winsorize(.,probs = c(.01,.99),na.rm = TRUE)))))

[[1]]
  id country price quality price_w quality_w
1  1       A   2.1     3.1   2.100     3.100
2  5       A   4.6     5.2   4.564     5.124
3  7       C   3.7     3.3   3.700     3.300
4  9       E   2.9     1.7   2.900     1.700
5 12       E   1.8     0.9   1.812     0.932

[[2]]
  id country price quality price_w quality_w
1  2       F   1.8     4.3   1.844     4.300
2  3       F   5.2     2.5   5.176     2.500
3  4       A   2.9     6.9   2.900     6.796
4 10       Z   4.6     1.9   4.600     1.900
5 14       X   3.9     0.8   3.900     0.844
,

这是一个data.table解决方案

library( data.table )
library( DescTools )
#make df1 and df2 a data.table
my.list <- lapply( my.list,setDT )
#rund function on columns
lapply( my.list,function(x) {
  x[,paste0( (cols),"_w" ) := DescTools::Winsorize( .SD,probs = c(0.1,0.9),na.rm = TRUE ),.SDcols = cols]
})

# 
# [[1]]
#    id country price quality price_w quality_w
# 1:  1       A   2.1     3.1     2.1      3.10
# 2:  5       A   4.6     5.2     4.6      4.66
# 3:  7       C   3.7     3.3     3.7      3.30
# 4:  9       E   2.9     1.7     2.9      1.70
# 5: 12       E   1.8     0.9     1.8      1.62
# 
# [[2]]
#    id country price quality price_w quality_w
# 1:  2       F   1.8     4.3     1.8      4.30
# 2:  3       F   5.2     2.5     5.2      2.50
# 3:  4       A   2.9     6.9     2.9      5.37
# 4: 10       Z   4.6     1.9     4.6      1.90
# 5: 14       X   3.9     0.8     3.9      1.70

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。