我正在处理一个较大的数据框,因此我需要用列名替换所有的那些,但是我不知道如何使它起作用。任何人都知道如何进行这项工作。
这是我的数据:
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)
这两者都给了我第一行而不是列标题。
谢谢您的帮助。
答案 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)
假设数据框中仅包含1
或0
,则可以按名称使用数据框的乘积。试试:
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