【问题标题】:Add repeated-measures column names as prefix instead of suffix using reshape使用 reshape 添加重复测量列名称作为前缀而不是后缀
【发布时间】:2015-12-08 14:09:24
【问题描述】:

我正在使用基础 R 中的 reshape 函数将用于重复测量设计的长格式数据帧转换为宽格式。请参阅下面的玩具数据集。问题 1、2 和 3 是对三项调查的个人回答。有四名参与者,每人参加四次调查。

Q1 <- c(2,6,5,4,3,8,9,2,1,5,4,7,3,7,2,1)
Q2 <- c(4,7,6,3,1,2,5,6,7,5,4,3,5,6,6,3)
Q3 <- c(7,9,3,1,5,3,7,5,3,3,5,7,8,9,9,3)
Participant <- rep(c("Bob","Sue","Jim","Tom"), times = 1, each = 4)
Time <- rep(c("FirstSurvey","SecondSurvey","ThirdSurvey","FourthSurvey"), times = 4)

m <- as.data.frame(cbind(Participant, Time, Q1, Q2, Q3))

这会产生以下数据框

m

   Participant         Time Q1 Q2 Q3
1          Bob  FirstSurvey  2  4  7
2          Bob SecondSurvey  6  7  9
3          Bob  ThirdSurvey  5  6  3
4          Bob FourthSurvey  4  3  1
5          Sue  FirstSurvey  3  1  5
6          Sue SecondSurvey  8  2  3
7          Sue  ThirdSurvey  9  5  7
8          Sue FourthSurvey  2  6  5
9          Jim  FirstSurvey  1  7  3
10         Jim SecondSurvey  5  5  3
11         Jim  ThirdSurvey  4  4  5
12         Jim FourthSurvey  7  3  7
13         Tom  FirstSurvey  3  5  8
14         Tom SecondSurvey  7  6  9
15         Tom  ThirdSurvey  2  6  9
16         Tom FourthSurvey  1  3  3

如果你这样重塑它:

mReshaped <- reshape(m, idvar = "Participant", timevar = "Time", direction = "wide", sep = "", new.row.names = c(1,2,3,4))

它产生以下宽格式数据帧:

mReshaped

  Participant Q1FirstSurvey Q2FirstSurvey Q3FirstSurvey Q1SecondSurvey Q2SecondSurvey
1         Bob             2             4             7              6              7
2         Sue             3             1             5              8              2
3         Jim             1             7             3              5              5
4         Tom             3             5             8              7              6
  Q3SecondSurvey Q1ThirdSurvey Q2ThirdSurvey Q3ThirdSurvey Q1FourthSurvey Q2FourthSurvey
1              9             5             6             3              4              3
2              3             9             5             7              2              6
3              3             4             4             5              7              3
4              9             2             6             9              1              3
  Q3FourthSurvey
1              1
2              5
3              7
4              3

具有以下列名称

colnames(mReshaped)

 [1] "Participant"    "Q1FirstSurvey"  "Q2FirstSurvey"  "Q3FirstSurvey"  "Q1SecondSurvey"
 [6] "Q2SecondSurvey" "Q3SecondSurvey" "Q1ThirdSurvey"  "Q2ThirdSurvey"  "Q3ThirdSurvey" 
[11] "Q1FourthSurvey" "Q2FourthSurvey" "Q3FourthSurvey"

如您所见,当数据框被重塑时,重塑函数将时间变量作为后缀添加到每个重复测量的列名称中。

有谁知道reshape函数中是否有一个参数允许您选择将Time变量作为前缀,在每个Value变量名称的前面

【问题讨论】:

    标签: r reshape


    【解决方案1】:

    我不确定您是否可以在reshape 中更改顺序,但您可以在之后使用带有正则表达式的gsub 进行更改:

    names(mReshaped) = gsub("(Q[0-9])(.*)", "\\2\\1", names(mReshaped))
    
     [1] "Participant"    "FirstSurveyQ1"  "FirstSurveyQ2"  "FirstSurveyQ3"  "SecondSurveyQ1"
     [6] "SecondSurveyQ2" "SecondSurveyQ3" "ThirdSurveyQ1"  "ThirdSurveyQ2"  "ThirdSurveyQ3" 
    [11] "FourthSurveyQ1" "FourthSurveyQ2" "FourthSurveyQ3"
    

    更新: 代码工作原理说明:代码使用正则表达式(或简称“正则表达式”),这是一种文本处理语言,您第一次看到它时会非常神秘。

    在这种情况下,Q[0-9] 表示匹配“Q”后跟任意数字。 (Q[0-9]) 将该匹配转换为“捕获组”,这意味着我们可以稍后再参考它。这是捕获组#1。

    .* 表示匹配所有剩余的字符(在Q[0-9] 匹配的字符之后出现的任何字符)。 . 表示匹配任意单个字符;添加* 表示匹配任意长度的任意字符串。 (.*) 将匹配转换为捕获组#2。

    \\2\\1 获取我们捕获的两个字符串并反转它们的顺序。

    正则表达式对于像这样的文本操作任务非常有用。了解更多关于它们的几个地方是 hereherehere

    【讨论】:

    • 谢谢,效果很好,但我不太明白它是如何工作的。例如,(.*) 和 "//2//1" 参数有什么作用。
    • 我发现很难根据我的实际数据使您的答案适应列名。有什么方法可以删除最后两个字符,它们是时间码变量名称(在我的例子中是一个字母和一个数字(B1、B2、T1、T2、T3、T4、T5、T6、T7、T8、T9 )) 从每个列名中添加它们作为前缀?
    • 如果你想去掉最后两个字符,并且它们总是一个大写字母后跟一个数字,那么下面应该可以工作:gsub("(Q[0-9])(.*)([A-Z][0-9])$", "\\3\\2\\1", names(mReshaped)). Note that we matched and captured the last two characters with ([AZ][0-9] )$, meaning any capital letter followed by any digit. The $` 表示最后两个字符必须是字符串的结尾。我们将它们放在第三个捕获组中,并将其放在替换字符串中的第一个。让我知道这是否能解决您的问题。
    • 谢谢。但我似乎无法让您发送的脚本开始工作。我创建了一个向量:varNom
    • varNom 是字符串向量,而不是数据框的列名。所以如果你想改变这些字符串,你可以这样做:gsub("(Q[0-9])(.*)([A-Z][0-9])$", "\\3\\2\\1", varNom)。但是,我的代码基于它们是需要重新排列的三个子字符串,而我在 varNom 中只看到两个。比如你想把secondwordB2变成B2secondword等等,那么你想:gsub("(.*)([A-Z][0-9])$", "\\2\\1", varNom)
    猜你喜欢
    • 2023-01-05
    • 2014-09-29
    • 1970-01-01
    • 1970-01-01
    • 2012-10-03
    • 2013-01-30
    • 2016-03-07
    • 1970-01-01
    相关资源
    最近更新 更多