如何用列名替换数据框中的1

时间:2018-10-04 15:28:46

标签: r

我正在处理一个较大的数据框,因此我需要用列名替换所有的那些,但是我不知道如何使它起作用。任何人都知道如何进行这项工作。

这是我的数据:

Names 35 40 45 50 55 60
a      1  0  1  0  0  0
b      0  0  0  1  0  0
c      0  1  0  1  1  0
d      1  0  0  0  0  1

这是我的代码:

df[,-1] <- sapply(df[,-1], function(x) {ind <- which(x!=0); x[ind] = 
df[ind,1]; return(x)})

mat <- as.matrix(df[, -1])
pos <- which(mat != 0)
mat[pos] <- rep(df[[1]], times = ncol(mat))[pos]
new_dat <- "colnames<-"(cbind.data.frame(df[1], mat), colnames)

这两者都给了我第一行而不是列标题。

谢谢您的帮助。

3 个答案:

答案 0 :(得分:1)

我们用col创建一个索引,然后根据它进行替换

m1 <- col(df1[-1]) * df1[-1]
i1 <- m1 != 0
df1[-1][i1] <- rep(colnames(m1), each = nrow(m1))[i1]
df1
#   Names 35 40 45 50 55 60
#1     a 35  0 45  0  0  0
#2     b  0  0  0 50  0  0
#3     c  0 40  0 50 55  0
#4     d 35  0  0  0  0 60

注意:当列名不是数字时,这也应该起作用。最好不要以数字开头的列名


或者如果它是数字,我们可以在复制后简单地相乘

df1[-1] <- df1[-1] * as.numeric(names(df1)[-1])[col(df1[-1])]

或使用for循环

for(i in 2:ncol(df1)) df1[[i]][df1[[i]]==1] <- as.numeric(names(df1)[i])

数据

df1 <- structure(list(Names = c("a", "b", "c", "d"), `35` = c(1L, 0L, 
0L, 1L), `40` = c(0L, 0L, 1L, 0L), `45` = c(1L, 0L, 0L, 0L), 
`50` = c(0L, 1L, 1L, 0L), `55` = c(0L, 0L, 1L, 0L), `60` = c(0L, 
0L, 0L, 1L)), class = "data.frame", row.names = c(NA, -4L
))

答案 1 :(得分:1)

假设数据框中仅包含10,则可以按名称使用数据框的乘积。试试:

cbind(df[1], mapply(`*`, df[-1], as.numeric(colnames(df[-1]))))
# or just cbind(df[1], df[-1] * as.numeric(colnames(df[-1])))
# output
  Names 35 40 45 50 55 60
1     a 35  0 45  0  0  0
2     b  0  0  0 50  0  0
3     c  0 40  0 50 55  0
4     d 35  0  0  0  0 60
# data
df <- structure(list(Names = structure(1:4, .Label = c("a", "b", "c", 
"d"), class = "factor"), `35` = c(1L, 0L, 0L, 1L), `40` = c(0L, 
0L, 1L, 0L), `45` = c(1L, 0L, 0L, 0L), `50` = c(0L, 1L, 1L, 0L
), `55` = c(0L, 0L, 1L, 0L), `60` = c(0L, 0L, 0L, 1L)), .Names = c("Names", 
"35", "40", "45", "50", "55", "60"), class = "data.frame", row.names = c(NA, 
-4L))

答案 2 :(得分:1)

此解决方案遍历并在每列上应用简单的ifelse()

df[-1] <- lapply(seq_along(df)[-1], function(x) ifelse(df[[x]] == 1, names(df)[x], df[[x]]))
df  

  Names 35 40 45 50 55 60
1     a 35  0 45  0  0  0
2     b  0  0  0 50  0  0
3     c  0 40  0 50 55  0
4     d 35  0  0  0  0 60