使用lapply将r中某个值的所有元素逐列更改为另一个值



对于数据帧中的每一列,我想用列号替换所有非零值。例如,如果我有这样一个数据帧:

> df1 <- as.data.frame(matrix(c(0,0.1,0,0.1,0,0.1,0,0.1,0,0.1,0,0.1), nrow = 4, ncol = 3))
> df1
V1  V2  V3
1 0.0 0.0 0.0
2 0.1 0.1 0.1
3 0.0 0.0 0.0
4 0.1 0.1 0.1

我想把它改成:

>df2
V1 V2 V3
1  0  0  0  
2  1  2  3
3  0  0  0
4  1  2  3

我尝试了下面的多种变体,但都没有成功——我就是想不明白lapply调用中的函数是指什么。

counter <- 0
lapply(df1, function(x){
df1[,x][df1[,x]>0] <- counter
counter <<- counter+1
})
counter <- 0
lapply(df1, function(x){
x[][x[]>0] <- counter
counter <<- counter+1
})

可以用更紧凑的方式完成

df1[] <-  col(df1) * !!df1

与产出

df1
#  V1 V2 V3
#1  0  0  0
#2  1  2  3
#3  0  0  0
#4  1  2  3

将'df1'转换为逻辑矩阵,即非零值为TRUE,零值为FALSE (!!df1),并与列索引(col(df1))相乘,以便任何值为FALSE ->0和TRUE ->1、返回列索引


dplyr

中的其他选项
library(dplyr)
df1 %>% 
mutate(across(everything(), ~  match(cur_column(), names(df1)) * (. != 0)))

如果要使用lapply并访问列号,则遍历列号:

df1[] = lapply(seq_along(df1), function(i) {
replace(df1[[i]], df1[[i]] != 0, i)
})
df1
#   V1 V2 V3
# 1  0  0  0
# 2  1  2  3
# 3  0  0  0
# 4  1  2  3

当使用lapply修改列时,请记住,赋值必须在lapply调用之外进行。使用像data[] = lapply(...)这样的括号是一个有用的技巧,这样lapply返回的list被解释为数据帧的列。

相关内容

最新更新