这是我的数据的一个非常小的子集。我有超过 20000 个变量和 700 个变量。我想要做的是获取变量的子集,并创建一个新变量,该变量的变量名称为该子集的值为 1。这些子集中的所有变量都将是字符变量。嗯>
id gen16 gen18 gen31 gen33 gen35 gen39 gen45 gen51 gen52 gen56 gen58 gen59 gen66 gen68
5962 1 1 2 2 2 2 2 2 2 1 2 2 2 1 2
6085 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2
6183 3 1 2 2 2 2 2 2 2 2 2 2 2 2 2
6386 4 1 2 2 2 2 2 2 2 2 2 2 2 2 2
6989 5 1 2 1 2 2 2 2 2 2 2 2 2 2 2
7057 6 2 1 1 2 2 2 1 2 2 2 2 2 2 2
7276 7 2 2 2 2 2 2 2 1 1 2 2 2 1 2
7748 8 2 1 2 2 2 2 2 1 2 2 2 2 2 2
7917 9 2 2 2 2 2 2 2 1 2 2 2 2 2 2
8654 10 2 2 2 2 2 2 2 2 2 2 2 1 2 2
这就是我正在寻找的东西。
id gen16 gen18 gen31 gen33 gen35 gen39 gen45 gen51 gen52 gen56 gen58 gen59 gen66 gen68 V1
5962 1 1 2 2 2 2 2 2 2 1 2 2 2 1 2 gen16, gen52, gen66
6085 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 gen58
6183 3 1 2 2 2 2 2 2 2 2 2 2 2 2 2 gen16
6386 4 1 2 2 2 2 2 2 2 2 2 2 2 2 2 gen16
6989 5 1 2 1 2 2 2 2 2 2 2 2 2 2 2 gen16, gen31
7057 6 2 1 1 2 2 2 1 2 2 2 2 2 2 2 gen18, gen31, gen45
7276 7 2 2 2 2 2 2 2 1 1 2 2 2 1 2 gen51, gen52, gen66
7748 8 2 1 2 2 2 2 2 1 2 2 2 2 2 2 gen18, gen51
7917 9 2 2 2 2 2 2 2 1 2 2 2 2 2 2 gen51
8654 10 2 2 2 2 2 2 2 2 2 2 2 1 2 2 gen59
我已经编写了一个 for 循环来执行此操作,但我想避免该循环,因为我的数据集只会变得更大。我的想法是编写一个适用于一行的函数,然后使用 apply 函数在整个数据集上迭代它。我很幸运地获得了两个适用于一行的不同函数,但在尝试在 apply 函数中使用它们时遇到了问题。
这是我编写的另外两个函数。
inf.type <- function(x) {
foo <- as.data.frame(x[, c("gen16", "gen18", "gen31", "gen33", "gen35",
"gen39", "gen45", "gen51", "gen52", "gen56", "gen58", "gen59", "gen66", "gen68")] == 1)
gentypes <- paste(names(foo[colSums(foo) == "1"]), collapse = ", ")
return(gentypes)
}
inf.type <- function(x) {
foo <- x[, c("gen16", "gen18", "gen31", "gen33", "gen35", "gen39", "gen45",
"gen51", "gen52", "gen56", "gen58", "gen59", "gen66", "gen68")]
return(paste(names(foo[grep("1", foo)]), collapse = ", "))
}
这两个似乎适用于单行,但在使用 apply 函数时则不然。如果有人可以帮助我弄清楚如何让其中一个在 apply 函数中工作,或者对完全不同的方法有更好的建议,我将不胜感激。
最佳答案
这应该可以完成工作:
df$V1 = apply(df[,-1], 1, function(x) paste(names(which(x=='1')), collapse = ", "))
这会查看df[,-1]
的每一行(不包括id
列),返回索引(带有which
)匹配x=='1'
,提取与这些索引相对应的名称
,并将每行的名称粘贴
在一起。
还可以编写以下内容(根据@alistaire的建议):
df$V1 = apply(df[, -1] == 1, 1, function(x) toString(names(x)[x]))
df[, -1] == 1
将 df[, -1]
转换为逻辑矩阵,每个单元格的计算结果为 TRUE
如果它等于1
,否则等于FALSE
。然后,可以提取每行的 TRUE
单元格的名称
,然后将名称与 toString
连接在一起。
结果:
id gen16 gen18 gen31 gen33 gen35 gen39 gen45 gen51 gen52 gen56 gen58 gen59
5962 1 1 2 2 2 2 2 2 2 1 2 2 2
6085 2 2 2 2 2 2 2 2 2 2 2 1 2
6183 3 1 2 2 2 2 2 2 2 2 2 2 2
6386 4 1 2 2 2 2 2 2 2 2 2 2 2
6989 5 1 2 1 2 2 2 2 2 2 2 2 2
7057 6 2 1 1 2 2 2 1 2 2 2 2 2
7276 7 2 2 2 2 2 2 2 1 1 2 2 2
7748 8 2 1 2 2 2 2 2 1 2 2 2 2
7917 9 2 2 2 2 2 2 2 1 2 2 2 2
8654 10 2 2 2 2 2 2 2 2 2 2 2 1
gen66 gen68 V1
5962 1 2 gen16, gen52, gen66
6085 2 2 gen58
6183 2 2 gen16
6386 2 2 gen16
6989 2 2 gen16, gen31
7057 2 2 gen18, gen31, gen45
7276 1 2 gen51, gen52, gen66
7748 2 2 gen18, gen51
7917 2 2 gen51
8654 2 2 gen59
数据:
df = structure(list(id = c("1", "2", "3", "4", "5", "6", "7", "8",
"9", "10"), gen16 = c("1", "2", "1", "1", "1", "2", "2", "2",
"2", "2"), gen18 = c("2", "2", "2", "2", "2", "1", "2", "1",
"2", "2"), gen31 = c("2", "2", "2", "2", "1", "1", "2", "2",
"2", "2"), gen33 = c("2", "2", "2", "2", "2", "2", "2", "2",
"2", "2"), gen35 = c("2", "2", "2", "2", "2", "2", "2", "2",
"2", "2"), gen39 = c("2", "2", "2", "2", "2", "2", "2", "2",
"2", "2"), gen45 = c("2", "2", "2", "2", "2", "1", "2", "2",
"2", "2"), gen51 = c("2", "2", "2", "2", "2", "2", "1", "1",
"1", "2"), gen52 = c("1", "2", "2", "2", "2", "2", "1", "2",
"2", "2"), gen56 = c("2", "2", "2", "2", "2", "2", "2", "2",
"2", "2"), gen58 = c("2", "1", "2", "2", "2", "2", "2", "2",
"2", "2"), gen59 = c("2", "2", "2", "2", "2", "2", "2", "2",
"2", "1"), gen66 = c("1", "2", "2", "2", "2", "2", "1", "2",
"2", "2"), gen68 = c("2", "2", "2", "2", "2", "2", "2", "2",
"2", "2")), class = "data.frame", .Names = c("id", "gen16", "gen18",
"gen31", "gen33", "gen35", "gen39", "gen45", "gen51", "gen52",
"gen56", "gen58", "gen59", "gen66", "gen68"), row.names = c(NA,
-10L))
关于r - 从满足给定条件的变量名称创建变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48286205/