使用R操作dataframe:将列的每一行分隔为不同的列
我有一个较长的数据框,包含学生姓名、科目、问题名称及其分数。此数据帧的简短版本如下所示:使用R操作dataframe:将列的每一行分隔为不同的列,r,dplyr,R,Dplyr,我有一个较长的数据框,包含学生姓名、科目、问题名称及其分数。此数据帧的简短版本如下所示: c1 c2 c3 c4 A 1 a 1 A 1 b 0.5 A 1 c 1 A 2 a 2 A 2 b 1.5 A 2 c 3 A 2 d 3 B 1 a 0 B 1 b 1.5 B 1 c 2 B 2 a 2 B 2 b 2.5 B 2 c 4 B 2 d 5 这里A、B是学生,1、2是科目
c1 c2 c3 c4
A 1 a 1
A 1 b 0.5
A 1 c 1
A 2 a 2
A 2 b 1.5
A 2 c 3
A 2 d 3
B 1 a 0
B 1 b 1.5
B 1 c 2
B 2 a 2
B 2 b 2.5
B 2 c 4
B 2 d 5
这里A、B是学生,1、2是科目,A、B、c是题名,最后一列是每个学生在每个科目和每个问题上获得的分数
我想合并dataframe的一部分,其中“问题名称”列成为几个列的标题,相应的标记如下:
Student Sub:1 Sub:2
Name a b c a b c d
A 1 0.5 1 2 1.5 3 3
B 0 1.5 2 2 2.5 4 5
我可以使用转置函数(t(dataframe)
)将列切换到行,但我不知道如何部分保留学生和分数的详细信息。
有人能指导我如何做到这一点吗?我们可以使用
pivot\u wide
,提供c2
和c3
列的列名和c4
列的值
tidyr::pivot_wider(df,names_from = c(c2, c3),values_from = c4, names_prefix = "Sub")
# c1 Sub1_a Sub1_b Sub1_c Sub2_a Sub2_b Sub2_c Sub2_d
# <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 A 1 0.5 1 2 1.5 3 3
#2 B 0 1.5 2 2 2.5 4 5
数据
df <- structure(list(c1 = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L,
2L, 2L, 2L, 2L, 2L, 2L), .Label = c("A", "B"), class = "factor"),
c2 = c(1L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 2L,
2L), c3 = structure(c(1L, 2L, 3L, 1L, 2L, 3L, 4L, 1L, 2L,
3L, 1L, 2L, 3L, 4L), .Label = c("a", "b", "c", "d"), class = "factor"),
c4 = c(1, 0.5, 1, 2, 1.5, 3, 3, 0, 1.5, 2, 2, 2.5, 4, 5)), class = "data.frame",
row.names = c(NA, -14L))
df这里是使用restrape()的基本R解决方案
查看dplyr
软件包中的pivot\u wide
,了解一种可以实现这一点的固定方法。感谢您提供的快速解决方案。我得到一个错误:错误:“pivot_wider”不是从'namespace:tidyr'@shiva导出的对象。我认为您需要更新tidyr
库,该函数来自tidyr 1.0.0。请安装.packages('tidyr')
,然后再试一次。谢谢您的帮助…我得到了一个数据框,里面充满了像1 BDSF1146 2 BDSF1324这样的值。我做错了什么吗?@shiva您有与问题中所示相同的数据吗?或者你有其他的专栏吗?你能使用我在回答中分享的数据,看看它是否给出了如图所示的输出吗?有一个重复的条目,我修复了它,它工作得很好。谢谢
df <- structure(list(c1 = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L,
2L, 2L, 2L, 2L, 2L, 2L), .Label = c("A", "B"), class = "factor"),
c2 = c(1L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 2L,
2L), c3 = structure(c(1L, 2L, 3L, 1L, 2L, 3L, 4L, 1L, 2L,
3L, 1L, 2L, 3L, 4L), .Label = c("a", "b", "c", "d"), class = "factor"),
c4 = c(1, 0.5, 1, 2, 1.5, 3, 3, 0, 1.5, 2, 2, 2.5, 4, 5)), class = "data.frame",
row.names = c(NA, -14L))
df$namecol <- with(df,paste0(c2,c3))
dfout <- reshape(df[-c(2:3)],direction = "wide",idvar = "c1",timevar = "namecol")
names(dfout) <- gsub(".*\\.(.*)","\\1",names(dfout))
> dfout
c1 1a 1b 1c 2a 2b 2c 2d
1 A 1 0.5 1 2 1.5 3 3
8 B 0 1.5 2 2 2.5 4 5