Преобразование разделенных запятыми элементов в столбцы
У меня есть набор данных с несколькими столбцами, один из которых является столбцом для времени реакции. Эти времена реакции разделяются запятыми, чтобы обозначать времена реакции (одного и того же участника) для разных испытаний.
Например: строка 1 (т.е. данные от участника 1) имеет следующее под столбцом "время реакции"
reaction_times
2000,1450,1800,2200
Следовательно, это время реакции участника 1 для испытаний 1,2,3,4
.
Теперь я хочу создать новый набор данных, в котором время реакции для этих испытаний будет составлять отдельные столбцы. Таким образом, я могу рассчитать среднее время реакции для каждого испытания.
trial 1 trial 2 trial 3 trial 4
participant 1: 2000 1450 1800 2200
Я попробовал "colsplit" из пакета "reshape2", но это, похоже, не разбивает мои данные на новые столбцы (возможно, потому, что мои данные все в 1 ячейке).
Любые предложения?
Ответы
Ответ 1
Я думаю, что вы ищете функцию strsplit(),
a = "2000,1450,1800,2200"
strsplit(a, ",")
[[1]]
[1] "2000" "1450" "1800" "2200"
Обратите внимание, что strsplit возвращает список, в этом случае только с одним элементом. Это связано с тем, что strsplit принимает в качестве вектора векторы. Таким образом, вы также можете поместить длинный вектор ваших персонажей из одной ячейки в функцию и вернуть разбитый список этого вектора. В более подходящем примере это выглядит так:
# Create some example data
dat = data.frame(reaction_time =
apply(matrix(round(runif(100, 1, 2000)),
25, 4), 1, paste, collapse = ","),
stringsAsFactors=FALSE)
splitdat = do.call("rbind", strsplit(dat$reaction_time, ","))
splitdat = data.frame(apply(splitdat, 2, as.numeric))
names(splitdat) = paste("trial", 1:4, sep = "")
head(splitdat)
trial1 trial2 trial3 trial4
1 597 1071 1430 997
2 614 322 1242 1140
3 1522 1679 51 1120
4 225 1988 1938 1068
5 621 623 1174 55
6 1918 1828 136 1816
и, наконец, рассчитать среднее значение для человека:
apply(splitdat, 1, mean)
[1] 1187.50 361.25 963.75 1017.00 916.25 1409.50 730.00 1310.75 1133.75
[10] 851.25 914.75 881.25 889.00 1014.75 676.75 850.50 805.00 1460.00
[19] 901.00 1443.50 507.25 691.50 1090.00 833.25 669.25
Ответ 2
Изящным, хотя и довольно тяжелым способом, является использование read.csv
в сочетании с textConnection
. Предполагая, что ваши данные находятся в кадре данных, df
:
x <- read.csv(textConnection(df[["reaction times"]]))
Ответ 3
Старый вопрос, но я наткнулся на него из еще одного недавнего вопроса (который кажется несвязанным).
Оба существующих ответа являются подходящими, но я хотел бы поделиться ответом, связанным с созданным мной пакетом, называемым "splitstackshape", который является быстрым и имеет простой синтаксис.
Вот некоторые примеры данных:
set.seed(1)
dat = data.frame(
reaction_time = apply(matrix(round(
runif(24, 1, 2000)), 6, 4), 1, paste, collapse = ","))
Это расщепление:
library(splitstackshape)
cSplit(dat, "reaction_time", ",")
# reaction_time_1 reaction_time_2 reaction_time_3 reaction_time_4
# 1: 532 1889 1374 761
# 2: 745 1322 769 1555
# 3: 1146 1259 1540 1869
# 4: 1817 125 996 425
# 5: 404 413 1436 1304
# 6: 1797 354 1984 252
И, необязательно, если вам нужно взять rowMeans
:
rowMeans(cSplit(dat, "reaction_time", ","))
# [1] 1139.00 1097.75 1453.50 840.75 889.25 1096.75
Ответ 4
Другая опция, использующая dplyr и tidyr с примерами примера Paul Hiemstra:
# create example data
data = data.frame(reaction_time =
apply(matrix(round(runif(100, 1, 2000)),
25, 4), 1, paste, collapse = ","),
stringsAsFactors=FALSE)
head(data)
# clean data
data2 <- data %>% mutate(split_reaction_time = str_split(as.character(reaction_time), ",")) %>% unnest(split_reaction_time)
data2$col_names <- c("trial1", "trial2", "trial3", "trial4")
data2 <- data2 %>% spread(key = col_names, value = split_reaction_time) %>% select(-reaction_time)
head(data2)