我有两个数据框。可重复的例子如下:
structure(list(`1` = c(0L, 1L, 1L), `2` = c(1L, 0L, -1L), `3` = c(0L,
0L, 0L), `4` = c(0L, 0L, 0L), `5` = c(0L, 0L, 0L), `6` = c(0L,
0L, 0L), `7` = c(0L, -1L, 0L), `8` = c(0L, 0L, 0L), `9` = c(0L,
0L, 0L), `10` = c(0L, 0L, 0L), `11` = c(0L, 0L, 0L), `12` = c(0L,
0L, 0L), `13` = c(0L, 0L, 0L), `14` = c(0L, 0L, 0L), `15` = c(0L,
0L, 0L), `16` = c(0L, 0L, 0L), `17` = c(0L, 0L, 0L), `18` = c(0L,
0L, 0L), `19` = c(0L, 0L, 0L), `20` = c(0L, 0L, 0L), `21` = c(0L,
0L, 0L), `22` = c(0L, 0L, 0L), `23` = c(0L, 0L, 0L), `24` = c(-1L,
0L, 0L)), .Names = c("1", "2", "3", "4", "5", "6", "7", "8",
"9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
"20", "21", "22", "23", "24"), row.names = c(3L, 6L, 12L), class = "data.frame")
这有24列,每列代表语句。第二个数据框如下:
structure(list(Level = c(1L, 1L, 1L, 1L), Statement = c("attr1",
"attr2", "attr24", "attr7"), StmtNo = c(1L, 2L, 24L, 7L)), .Names = c("Level",
"Statement", "StmtNo"), row.names = c(NA, 4L), class = "data.frame")
此第二个数据框有一个名称为StmtNo的列。这是df1中列的相应数字。例如,DF2中的StmtNo 1与DF1的第1列匹配。
我想做的是:
对于DF1中值为0的所有单元格,我必须将DF1中的列号与DF2的StmtNo列匹配。如果列号匹配,则单元格值应为0,如果不匹配,则该值应为NA。我尝试使用if with if条件:
df1 <- apply(df1, function(x) if (x == 0) {
if (exists(colnames(df1)) %in% df2$StmtNo) {
x == NA
} else {
x == 0
}
})
但是这会返回一个逻辑列表。我想要的输出如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
3 0 1 NA NA NA NA 0 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA -1
6 1 0 NA NA NA NA -1 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA 0
12 1 -1 NA NA NA NA 0 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA 0
虽然上面填写NA的内容看起来很均匀,但我有60个这样的文件,每个文件都有不同的列,需要填写NA。
答案 0 :(得分:3)
这是尝试使用data.frame
对象的一些索引。
基本选择返回:
!names(df1)[col(df1)] %in% df2$StmtNo & df1==0
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
#3 FALSE FALSE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
#6 FALSE FALSE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
#12 FALSE FALSE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
这意味着你可以这样做:
df1[!names(df1)[col(df1)] %in% df2$StmtNo & df1==0] <- NA
df1
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
#3 0 1 NA NA NA NA 0 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA -1
#6 1 0 NA NA NA NA -1 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA 0
#12 1 -1 NA NA NA NA 0 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA 0
答案 1 :(得分:1)
一种不那么优雅的蛮力方法
cols <- names(df1)[!names(df1) %in% df2$StmtNo]
df <- data.frame( matrix(NA, ncol = length(cols), nrow = 3) )
names(df) <- cols
df <- cbind(df, df1[, df2$StmtNo])
df[, order(as.numeric(names(df)))]
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
# 3 0 1 NA NA NA NA 0 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA -1
# 6 1 0 NA NA NA NA -1 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA 0
# 12 1 -1 NA NA NA NA 0 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA 0