Можете ли вы назвать столбцы по номеру для условного поиска в R? - PullRequest
0 голосов
/ 25 июня 2019

У меня есть фрагмент кода, который проверяет фрейм данных и условно заменяет значение столбца V2 на объединенные значения столбцов V1 и V4 IF column V2 == "."

Итак, мой код:

data_file$V2[data_file$V2 == "."] = paste(data_file$V1[data_file$V2 == "."], data_file$V4[data_file$V2 == "."], sep = "_")

И когда это применимо к кадру данных, как это:

V1 V2 V3 V4 V5 V6
1 rs796086906 0 13868 G A
1 . 0 14354 A C
1 rs62635297 0 14653 T C
1 . 0 14907 G A

Вывод выглядит так:

V1 V2 V3 V4 V5 V6
1 rs796086906 0 13868 G A
1 1_14354 0 14354 A C
1 rs62635297 0 14653 T C
1 1_14907 0 14907 G A

Тогда мой вопрос в основном академический. Поскольку этот код основан на знании имен столбцов заблаговременно (а при переборе множества файлов также используются столбцы с одинаковыми именами), мне было интересно, есть ли способ сделать то же самое, но вызывать столбцы по их номерам.

Так что-то вроде этого:

data_file[,2][data_file[,2] == "."] = paste(data_file[,1][data_file[,2] == "."], data_file[,4][data_file[,2] == "."], sep = "_")

Однако этот фрагмент кода не работает.

Возможно ли это на самом деле или это бессмысленное упражнение?

1 Ответ

1 голос
/ 25 июня 2019

Есть способ, но он может быстро запутаться в зависимости от того, как названы столбцы. Я предпочитаю динамически кодировать, используя следующее выражение

eval(parse(text = p.text))

где p.text - это строка кода, которую я хочу запустить. Поэтому, когда у меня есть строка, которую я хотел бы выполнить динамически, возникает ряд условий, которые мне нужно выполнить в первую очередь. А именно, мне понадобится функция, которая будет надежно создавать объект p.text для имитации вашей строки кода

data_file$V2[data_file$V2 == "."] <- paste(data_file$V1[data_file$V2 == "."],
                                          data_file$V4[data_file$V2 == "."], sep = "_")

Самый простой способ использовать индексы с моим ответом будет следующим:

#Get column names
cNam <- colnames(file)
#Assume cNam is c("V1","V2","V3","V4","V5")
#Build p.text
p.text <- paste(sep = "",
                "file$",
                cNam[2],
                "[file$",
                 cNam[2],
                 "==\".\"] <- paste(file$",
                 cNam[1],
                "[file$",
                cNam[2],
                "==\".\"], file$",
                cNam[4],
                "[file$",
                cNam[2],
                "==\".\"], sep = \"_\")")
p.text
# [1] "file$V2[file$V2==\".\"] <- paste(file$V1[file$V2==\".\"], file$V4[file$V2==\".\"], sep = \"_\")"
eval(parse(text = p.text))

Но опять же, это очень грязно и может легко сломаться, если вы не считаете, что некоторые имена столбцов могут содержать пробелы и другие символы, для работы которых требуются экранирующие метки. Таким образом, у вас может быть вспомогательная функция для обтекания любой переменной, в которой хранятся имена столбцов, которые будут возвращать имена столбцов с этими метками, чтобы они правильно вызывались в нотации. Как это

parseFriendly <- function(x) {
    x <- ifelse(stringr::str_detect(string = x, pattern = " "), paste(sep = "", "`",x,"`"), x )
}
#there are a number of special characters that require checking for besides spaces
#Such as: ?, +, -, /, #, =, @, !, %, ^, &, *, (, ),:
#basically almost anything that isnt a letter or a number excluding _ and .
#But spaces are the most common

Этот код также позволит вам динамически работать с именами файлов. (если вы хотите действительно сойти с ума по этому поводу)

#Store File variable name
fNam <- "My_new_file"
#Get column names
cNam <- eval(parse( text = paste(sep = "", "colnames(",fNam,")")))
#Assume cNam is c("bull dog","Poodle","Pug","Beagle","Boxer")
#Build p.text
p.text <- paste(sep = "",
                fNam, "$",
                parseFriendly(cNam[2]),
                "[",fNam, "$",
                 parseFriendly(cNam[2]),
                 "==\".\"] <- paste(",fNam, "$",
                 parseFriendly(cNam[1]),
                "[",fNam,"$",
                parseFriendly(cNam[2]),
                "==\".\"], ",fNam,"$",
                parseFriendly(cNam[4]),
                "[",fNam,"$",
                parseFriendly(cNam[2]),
                "==\".\"], sep = \"_\")")
p.text
# [1] "my_new_file$Poodle[my_new_file$Poodle==\".\"] <- paste(my_new_file$`bull dog`[my_new_file$Poodle==\".\"], my_new_file$Beagle[my_new_file$Poodle==\".\"], sep = \"_\")"

Я много писал, но я надеюсь, что это даст вам представление о том, как кодировать динамически.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...