基于列的值创建新变量

时间:2018-04-19 21:31:54

标签: r

我的数据框与下面的简化版相似:

MO1<-c("0","1","2","3")
MO2<-c("1","0","3","2")
MO3<-c("3","2","1","0")
df<-data.frame(MO1,MO2,MO3)
df

我正在尝试创建一个新变量,该变量将扫描观察所有1个值。然后,我希望这个新变量中的观察结果采用从中获取的列变量的名称,见下文:

MO1<-c("0","1","2","3")
MO2<-c("1","0","3","2")
MO3<-c("3","2","1","0")
MOTIVATION<-c("MO2","MO1","MO3","")
df2<-data.frame(MO1,MO2,MO3,MOTIVATION)
df2

抱歉,我不知道如何从上面显示结果数据框df2。

我的数据集中有989个观察值和19个不同的MO ..变量。

4 个答案:

答案 0 :(得分:2)

另一个选择

> ind <- which(df==1, arr.ind = TRUE)
> df2 <- df   # just cloning df
> df2$MOTIVATION <- NA
> df2$MOTIVATION[ind[,1]] <- names(df) [ind[,2]]
> df2
  MO1 MO2 MO3 MOTIVATION
1   0   1   3        MO2
2   1   0   2        MO1
3   2   3   1        MO3
4   3   2   0       <NA>

答案 1 :(得分:1)

1)像这样试试max.col。在每行前面插入1,然后找到最后一列的1。减去1,使其对应原始列号,缺少1给出0.然后用NA替换所有零,并查找相应的列名。

ix <- max.col(cbind(1, df) == 1, "last") - 1
transform(df, MOTIVATION = names(df)[replace(ix, ix == 0, NA)])

,并提供:

  MO1 MO2 MO3 MOTIVATION
1   0   1   3        MO2
2   1   0   2        MO1
3   2   3   1        MO3
4   3   2   0       <NA>

2)以下是一种变体。我们计算max.col,然后将每个结果乘以1,如果该行中有1,或者如果不是则为NA。

df1 <- df == 1
transform(df, MOTIVATION = names(df)[max.col(df1) * match(rowSums(df1), 1)])

答案 2 :(得分:1)

选项是将whichdf$MOTIVATION <- apply(df,1,function(x)names(df)[which(x==1)]) df # MO1 MO2 MO3 MOTIVATION # 1 0 1 3 MO2 # 2 1 0 2 MO1 # 3 2 3 1 MO3 # 4 3 2 0 结合使用:

cxfreeze

答案 3 :(得分:0)

以下是诀窍(请注意,这支持两列具有&#34; 1&#34的情况;不确定这是否是适合您的有效边缘情况。 (我稍微修改了原版的MO4,以便它包含两个&#34; 1&#34;

MO1<-c("0","1","2","3")
MO2<-c("1","2","3","2")
MO3<-c("3","2","1","0")
MO4<-c("3","2","1","1")
df<-data.frame(MO1,MO2,MO3,MO4)
df


findx <- function(dfx) 
{
  idx <- which(dfx=="1")
  res <- lapply(idx, function(x) paste0('MO', x))
  res
}

found <- apply(df,2,findx)

newdf <- unlist(found)
newdf

输出

&#34; MO2&#34; &#34; MO1&#34; &#34; MO3&#34; &#34; MO3&#34; &#34; MO4&#34;