Преобразуйте фрейм данных с общим количеством наблюдений (человек) в один с рядами для каждого наблюдения (человек)
У меня есть набор данных, как это:
> df<-data.frame(gender=c(rep("male",3),rep("female",3)),
Age=c(rep("old",3),rep("young",3)),VAR=c(rep(1:3),rep(1:3)),
FEN1=c(21,26,29,30,6,11),FEN2=c(14,55,12,33,9,21),
FEN3=c(88,23,55,23,14,66))
Где FEN1, FEN2 и FEN3 содержат общее количество лиц, принадлежащих к этой группе и которые имеют характеристики столбцов VAR, Gender, Age, FEN.
И мне нужно изменить его на фрейм данных, где каждая строка принадлежит одному человеку (всего 536 строк) с характеристиками столбцов VAR, Gender, Age.
Ожидаемый результат будет содержать:
- 21 ряд с информацией: мужской, старый, 1, FEN1
- 14 рядов с информацией: мужской, старый, 1, FEN2
- 88 строк с информацией: мужской, старый, 1, FEN3
- 26 строк с информацией: мужской, старый, 2, FEN1
- 55 строк с информацией: мужской, старый, 2, FEN2
- 23 ряда с информацией: мужской, старый, 2, FEN3
- и так далее...
Я пытался сделать это вручную с помощью кода вроде:
> df2<-as.data.frame(1:536)
> FEN <- c(rep("FEN1",123), rep("FEN2",144), rep("FEN3",269))
> df2$FEN<-FEN
> Gender<-c(rep("male",...)...
Но, очевидно, это совсем не эффективно.
1 ответ
Решение
Вот один метод, который использует базовые методы R.
# get the vector names that are used to repeat
fenCats <- tail(names(df), 3)
# construct a list of data.frames where the rows have been repeated
# one data.frame for each of the FEN variables
temp <- Map(function(x) df[rep(seq_len(nrow(df)), x), 1:3], df[fenCats])
# combine list of data.frames and add column with FEN categories
dfNew <- cbind(do.call(rbind, temp),
"fenCats"=rep(fenCats, colSums(df[fenCats])))
мы можем проверить, что количество строк правильно с
nrow(dfNew) == sum(colSums(df[fenCats])) &
nrow(dfNew) == sum(rowSums(df[fenCats]))
[1] TRUE
В качестве дополнительной проверки мы также можем выполнить быструю проверку, потянув за первый ряд каждой группы, используя поднаборы и cumsum
:
dfNew[cumsum(unlist(df[,fenCats])),]
gender Age VAR fenCats
FEN1.1.20 male old 1 FEN1
FEN1.2.25 male old 2 FEN1
FEN1.3.28 male old 3 FEN1
FEN1.4.29 female young 1 FEN1
FEN1.5.5 female young 2 FEN1
FEN1.6.10 female young 3 FEN1
FEN2.1.13 male old 1 FEN2
FEN2.2.54 male old 2 FEN2
FEN2.3.11 male old 3 FEN2
FEN2.4.32 female young 1 FEN2
FEN2.5.8 female young 2 FEN2
FEN2.6.20 female young 3 FEN2
FEN3.1.87 male old 1 FEN3
FEN3.2.22 male old 2 FEN3
FEN3.3.54 male old 3 FEN3
FEN3.4.22 female young 1 FEN3
FEN3.5.13 female young 2 FEN3
FEN3.6.65 female young 3 FEN3