Я пытаюсь преобразовать свою матрицу в другой формат в R, но, поскольку у меня нет большого опыта кодирования с циклами for / if, я терплю неудачу. Любая помощь приветствуется.
Демонстрация моей матрицы выглядит следующим образом:
S K1 K1 K2 K2 K3 K3 K4 K4 K5 K5
1 A P A A A A P A A A
2 A A A A A A A A P P
3 A P A A A A P A A A
4 A P A A A A P A A A
5 A P A A A A A A P A
A = ОТСУТСТВУЕТ P = ПРИСУТСТВУЕТ
Я хотел бы получить имена столбцов для существующих столбцов и распечатать их. Каждый образец имеет 2 столбца P. Итак, конечный результат должен быть
S V1 V1
1 K1 K4
2 K5 K5
3 K1 K4
4 K1 K4
5 K1 K5
Я знаю, что это простой цикл for / if, но я не могу найти решение. У вас есть коды, чтобы это исправить?
у вас есть столбец с таким же названием? И почему вы решили, что вам здесь нужна петля? Я бы пошел с indx <- which(df == "P", arr.ind = TRUE) ; matrix(colnames(df)[indx[order(indx[, "row"]), "col"]], ncol = 2, byrow = TRUE)
(если df
- ваш фрейм данных / матрица)
Спасибо за вашу помощь! У меня есть столбцы с таким же названием. Я решил использовать цикл, потому что я не знаком с r и думаю как сценарий оболочки. Итак, могу ли я использовать это с теми же именами столбцов или мне нужно их изменить?
Вы пробовали мой код?
Я пытался. На самом деле это то, что я хотел, но я не могу распечатать результат в формате .txt или .csv, поскольку это индекс. Есть ли способ обойти это?
Одним из множества доступных вариантов может быть:
df_res <- cbind(df[1],t(apply(df[-1], 1, function(x)names(df)[which(x= = "P")+1])))
#write result to a csv file
write.csv(df_res, file = "d:\\MyData.csv",row.names=FALSE)
# S 1 2
# 1 1 K1 K4
# 2 2 K5 K5
# 3 3 K1 K4
# 4 4 K1 K4
# 5 5 K1 K5
Мне просто интересно, как OP создал такую матрицу / data.frame.
Данные:
df <- read.table(text =
"S K1 K1 K2 K2 K3 K3 K4 K4 K5 K5
1 A P A A A A P A A A
2 A A A A A A A A P P
3 A P A A A A P A A A
4 A P A A A A P A A A
5 A P A A A A A A P A",
header = TRUE, stringsAsFactors = FALSE)
#Change the name of columns
names(df) <- sub("(.*)\\.\\d+","\\1",names(df))
Кстати, теперь я заметил, что R не разрешал иметь столбцы с одинаковыми именами, и мои имена столбцов - K1, K1.1, K2, K2.2 ... Я тот нуб!
@Mystra Но вы можете изменить имена столбцов с помощью names(df)
. Если вы заметили, что я изменил его в data
с помощью names(df) <- c('S','K1', 'K1', 'K2', 'K2', 'K3', 'K3', 'K4', 'K4', 'K5', 'K5')
, вы можете попробовать это со своей стороны.
@Mystra Не беспокойся. обучение - это процесс, требующий времени. В какой-то момент каждый был новичком.
Это довольно уродливо, но это добавит .1
к именам каждого столбца с нечетным номером в вашем фрейме данных: names(df[seq.int(ncol(df))%%2 == 0]) <- paste0(names(df[seq.int(ncol(df))%%2 == 0]), '.1')
@Mystra Какие у вас сейчас названия столбцов? Я уверен, что мы легко разберемся. Просто дайте мне знать 10-20 названий столбцов.
Я пробовал colnames (df) <- gsub (". 1", "", colnames (df)), но это не сработало ..
@Mystra Я изменил свой ответ, включив способ изменения имени столбца. В основном это names(df) <- sub("(.*)\\.\\d+","\\1",names(df))
Ваш код работал у меня очень хорошо, единственная проблема в том, что я не могу использовать write.txt для получения данных. Есть ли какой-нибудь способ для этого?
csv в порядке, я думаю
@Mystra Я обновил свой ответ, включив в него код для записи в файл. Имя файла выбрали как d:\\MyData.csv
. Вы можете выбрать по своему усмотрению.
вы можете использовать data.table
library(data.table)
setDT(melt(df,1))[value= = "P"][order(S),as.list(sub("[.].*","",variable)),by=S]
S V1 V2
1: 1 K1 K4
2: 2 K5 K5
3: 3 K1 K4
4: 4 K1 K4
5: 5 K1 K5
Очень красивое решение. Если скорость или память вызывают беспокойство, использование setDT
перед melt
поможет.
Вроде неплохо, но я получил сообщение об ошибке «Ошибка в eval (.massagei (isub), x, parent.frame ()): объект 'value' не найден»
как называются имена столбцов при запуске setDT(melt(df,1))
?
0101, 0101, 0102, 0102, 0201, 0201 ... 596 столбцов с разными именами
у меня вопрос, когда вы запускаете a=setDT(melt(df,1));names(a)
, что вы получаете ??
"sample.id" "0101" "0101" "0102" "0102" "0103" "0103" "0201" "0201" "0202" в основном имена моих столбцов
в тот момент, когда вы расплавите свои данные, вы должны иметь их в длинном формате, таким образом, у вас будет три столбца.
Получил вот что: "sample.id" "переменная" "значение"
поэтому, когда я сделал = setDT (melt (hla_a, 1)) [value == "P"] [order (sample.id), as.list ( sub ("[.]. *", "", variable)), by = sample.id] я получил ошибку: 'Ошибка в [.data.table
(setDT (melt (hla_a, 1)) [value == "P"], order (sample.id),: j doesn 't оценивает одинаковое количество столбцов для каждой группы'
Хорошо, как вы можете сказать, есть столбец под названием value
, теперь вы можете попробовать a[value= = "P"][order(sample.id),as.list(sub("[.].*","",variable)),by=sample.id]
та же ошибка: ошибка в [.data.table
(a [value == "P"], order (sample.id), as.list (sub ("[.]. *",: j не соответствует тому же количеству столбцов) для каждой группы
mhh .. Это означает, что есть другие строки с большим количеством "P", чем другие
вы можете сделать что-то вроде b=a[value= = "P"][order(sample.id),.(V1=sub("[.].*","",variable),V2=sequence(.N)),by=sample.id];dcast(b,S~V2,value.var = "V1",fill=NA)
Что именно вы пробовали? Действительно ли ваши данные находятся в матрице или в data.frame?