合并类似命名的列

时间:2015-04-24 15:48:50

标签: r

我正在使用具有类似命名列的data.frame。表单有三个版本,版本被添加到列名的末尾,所以df看起来像这样:

var1  var2  var1x  var2x  var1y  var2z
1     2     NA     NA     NA     NA
NA     NA   1       2     NA     NA
NA     NA   1      3      NA     NA
4     NA    NA    NA      NA    7

因此,除了最后一个字母之外,还有许多列具有相同的名称。我想结合这些相似的列,以便最终得到类似的东西:

var1   var2 
1      2
1      2
1      3
4      7

有什么想法吗?

编辑:任何变量都不可能有多个答案。因此,例如,如果var1是2,则var1x和var1y是构造的NA。

4 个答案:

答案 0 :(得分:5)

var1<-rowMeans(df[,grepl("var1",names(df))],na.rm=TRUE)
var2<-rowMeans(df[,grepl("var2",names(df))],na.rm=TRUE)
cbind(var1,var2)

     var1 var2
[1,]    1    2
[2,]    1    2
[3,]    1    3
[4,]    4    7
当所有人都是NA

时,

rowMeans()会给出NaN 当所有人都是NA时,

已编辑更改为rowMeans以获取NA的新要求。 rowMeans给NaN,这是公平的,我只是认为足够接近NA。

如果你有很多关于多个版本的问题,我会用这样的东西自动完成整个过程:

list<-c("var1","var2")
get_col<-function(var){
  rowMeans(df[,grepl(var,names(df))],na.rm=TRUE)
}
newdf<-data.frame(do.call(cbind,lapply(list,get_col)))
names(newdf)<-list



   var1 var2
1    1    2
2    1    2
3    1    3
4    4    7
5  NaN  NaN

答案 1 :(得分:5)

这是另一个想法:

library(dplyr)

df %>% 
  transmute(n_var1 = rowMeans(select(., starts_with("var1")), na.rm = TRUE),
            n_var2 = rowMeans(select(., starts_with("var2")), na.rm = TRUE))

给出了:

#  n_var1 n_var2
#1      1      2
#2      1      2
#3      1      3
#4      4      7

答案 2 :(得分:3)

不是我实际上会这样做,但这里是一个使用排序的答案(按变量的前4个字符排序,然后按实际值排序):

t(apply(DF, 1, function(x) x[order(substr(names(DF), 1, 4), x)]))[, c(1, 4)]

产地:

     [,1] [,2]
[1,]    1    2
[2,]    1    2
[3,]    1    3
[4,]    4    7    

对所有NA都应该是健壮的。

答案 3 :(得分:2)

另一种选择是基于列名中的公共前缀split列,在逻辑矩阵(max.col)上创建!is.na(x1)的列索引,{{1使用行索引(cbind)来获取每行的非NA元素。

1:nrow(x1)

注意:如果所有元素都是sapply(split(names(df1), sub('[^0-9]*$', '',names(df1))), function(x) { x1 <- df1[x] x1[cbind(1:nrow(x1), max.col(!is.na(x1)))]}) # var1 var2 #[1,] 1 2 #[2,] 1 2 #[3,] 1 3 #[4,] 4 7 ,这也会返回NA

或使用NAsplitstackshape

dplyr

数据

library(dplyr)
library(splitstackshape)
add_rownames(df1) %>%
       merged.stack(var.stub=c('var1', 'var2'), sep='var.stubs',
                   atStart=FALSE) %>%
       .[, list(var1=var1[!is.na(var1)], var2=var2[!is.na(var2)])]
#   var1 var2
#1:    1    2
#2:    1    2
#3:    1    3
#4:    4    7