将值映射到不同变量的组中

Jul*_*rre 1 r

我想创建一个函数来将值映射到组,以及不同的变量.

df <- data.frame(x = c("a", "a", "b", "c", "c", "d", "e"), 
                 y = c(1, 5, 5, 1, 6, 8, 3), 
                 z = runif(7), 
                 stringsAsFactors = FALSE)
Run Code Online (Sandbox Code Playgroud)

例如,对于这些数据,对于变量x,我想将值"a","b"映射到"label1",将"c""d""e"映射到"label2",并且对于变量y map 1, 3成"code1",5,6,8成"code2".

groups <- list(x = list(label1 = c("a", "b"), label2 = c("c", "d", "e")), 
                  y = list(code1 = c(1, 3), code2 = c(5, 6, 8)))
Run Code Online (Sandbox Code Playgroud)

在这个例子中,我想要映射来自2个变量的值,但它可以是1,3,4 ......所以我不想为每个变量创建数据帧查找或逐个分配每个变量.这就是为什么我使用一个列表(我在函数参数中发现它更友好)并且不能使用$.+这是在函数内部使用,所以我不需要硬编码.

所以实际上我创建了这个函数:

f <- function(x, groups) {

  table <- reshape2::melt(groups)
  table <- split(table, table$L1)

  for (i in seq_along(table)) {
    x[names(table)[i]] <- table[[i]]$L2[match(x[,names(table)[i]], table[[i]]$value)]
  }
  return(x)
}
Run Code Online (Sandbox Code Playgroud)

这是我尝试使用嵌套列表获得"友好"组参数的最佳尝试.

我尝试了一种语法,dplyr::mutate例如myFunction(x = list(label1 = c("a", "b"), label2 = c("c", "d", "e")), y = list(code1 = c(1, 3), code2 = c(5, 6, 8)))可能非常好的语法,但这只是具有许多参数的更大函数的一部分所以我不认为这是可能的(至少我没有成功).

但我确信有更好的方法可以做到这一点,或者可能存在已经存在的功能.你有改进的想法吗?谢谢 !

Cat*_*ath 6

您可以尝试使用matchdata.frames作为您的通信:

# define the correspondences
df2 <- data.frame(v1=letters[1:5], v2=paste0("label", c(1,1,2,2,2)), stringsAsFactors=F)
df3 <- data.frame(v1=c(1, 3, 5, 6, 8), v2=paste0("code", c(1,1,2,2,2)), stringsAsFactors=F)

# change your variables
df$x <- df2$v2[match(df$x, df2$v1)]
df$y <- df3$v2[match(df$y, df3$v1)]
Run Code Online (Sandbox Code Playgroud)

编辑考虑到"新"问题的限制,这里是你可以做的,保持dfgroups原样:

tochange <- which(colnames(df) %in% names(groups))
df[, tochange] <- sapply(colnames(df)[tochange], 
                         function(x, equ, df){
                               subequ <- stack(equ[[x]])
                               df[, x] <- subequ$ind[match(df[, x],subequ$values)] 
                               return(df[, x])
                         }, equ=groups, df=df)
df
#       x     y         z
#1 label1 code1 0.6022695
#2 label1 code2 0.1366602
#3 label1 code2 0.2848924
#4 label2 code1 0.6427569
#5 label2 code2 0.1546344
#6 label2 code2 0.3201543
#7 label2 code1 0.6388446
Run Code Online (Sandbox Code Playgroud)

  • 关于downvote的解释可能很好,并帮助我学习一些东西(希望如此)...... (5认同)