如何在 R 中结合使用 apply() 和 match()?

How to use apply() combined with match() in R?

我正在尝试用 table 中的值替换数据框中的值。

df <- read.table(text=" v1  v3_1    v3_3    v3_4    v3_5    v4_1    v4_3    v4_4    v4_5    
    11  0   0   0   0   0   0   0   0   
                 12 0   0   0   0   0   0   0   0   
                 13 0   0   0   0   0   0   0   0   
                 14 0   0   0   0   0   0   0   0   
                 15 0   0   0   0   0   0   0   0   
                 21 0   0   0   0   0   0   0   0   
                 22 0   0   0   0   0   0   0   0   
                 23 0   0   0   0   0   0   0   0   
                 24 0   0   0   0   0   0   0   0   
                 25 0   0   0   0   0   0   0   0   ", header=T)
table <- read.table(text="  v1  v3  v4  
    11  0.419774852 0.646429258 
                    13  0.396813214 0.922897052 
                    14  0.874210969 0.022308197 
                    15  0.997159373 0.234000934 
                    21  0.062226556 0.171017067 
                    23  0.467930927 0.273295148 
                    24  0.318980872 0.17997447  
                    25  0.323878792 0.026514599 ", header=T)

变量 table$v3 应该替换变量 df$v3_1df$v3_5 中的值。变量 table$v4 应该将变量 df$v4_1 中的值替换为 df$v4_5.

问题是我无法弄清楚如何在一个 apply 命令中执行此操作。截至目前,我必须使用两个 apply 命令:

cols1 <- c("v3_1", "v3_3",  "v3_4", "v3_5")
cols2 <- c("v4_1", "v4_3",  "v4_4", "v4_5")
df[,cols1] <- apply(df[,cols1], 2, function(x) table[match(df$v1, table$v1), "v3"]) 
df[,cols2] <- apply(df[,cols2], 2, function(x) table[match(df$v1, table$v1), "v4"]) 

有什么方法可以用一个 apply 命令来完成这个吗?我试过类似的东西:

cols3 <- c("v3_1", "v3_3",  "v3_4", "v3_5", "v4_1", "v4_3", "v4_4", "v4_5")
df[,cols3] <- apply(df[,cols3], 2, function(x) table[match(df$v1, table$v1), c("v3", "v4")])

但这只是为每个 cols3 变量创建了一个 v3v4 变量。

你可以这样做:

sapply(colnames(table[-1]),function(x) df[df$v1 %in% table$v1,grepl(x,colnames(df))]<<-table[,x] )
> df
   v1       v3_1       v3_3       v3_4       v3_5      v4_1      v4_3      v4_4      v4_5
1  11 0.41977485 0.41977485 0.41977485 0.41977485 0.6464293 0.6464293 0.6464293 0.6464293
2  12 0.00000000 0.00000000 0.00000000 0.00000000 0.0000000 0.0000000 0.0000000 0.0000000
3  13 0.39681321 0.39681321 0.39681321 0.39681321 0.9228971 0.9228971 0.9228971 0.9228971
4  14 0.87421097 0.87421097 0.87421097 0.87421097 0.0223082 0.0223082 0.0223082 0.0223082
5  15 0.99715937 0.99715937 0.99715937 0.99715937 0.2340009 0.2340009 0.2340009 0.2340009
6  21 0.06222656 0.06222656 0.06222656 0.06222656 0.1710171 0.1710171 0.1710171 0.1710171
7  22 0.00000000 0.00000000 0.00000000 0.00000000 0.0000000 0.0000000 0.0000000 0.0000000
8  23 0.46793093 0.46793093 0.46793093 0.46793093 0.2732951 0.2732951 0.2732951 0.2732951
9  24 0.31898087 0.31898087 0.31898087 0.31898087 0.1799745 0.1799745 0.1799745 0.1799745
10 25 0.32387879 0.32387879 0.32387879 0.32387879 0.0265146 0.0265146 0.0265146 0.0265146

注意: <<- 的使用不被认为是好的做法,因为它可能很危险。

如果您对 lapply 满意:(不过还有更多更好的方法)

func <- function(x){
  l = grepl(x, colnames(df))   # create logical vec of which columns needs to be replaced
  df[df$v1 %in% table[[1]] ,l]=table[x] # substitute where l is TRUE
  df[l]                                 # return only the replaced column
}
cbind(df[1], lapply(colnames(table[-1]), func))