【问题标题】:Combining and Transforming Data Frames in R在 R 中组合和转换数据帧
【发布时间】:2017-04-30 22:35:56
【问题描述】:

我在 R 中有一堆看起来像这样的数据框:

print(output[2])
Button Intensity Acc Intensity RT    Time tdelta SubjectID CoupleID PrePost
 1:      0        30   0       0.0  0 83325.87  0.000      1531 153    Post
 2:      1        30   1      13.5  0 83362.65 36.782      1531 153    Post
 3:      1        30   1      15.0  0 83376.68 14.027      1531 153    Post
 4:      1        30   1       6.0  0 83392.27 15.585      1531 153    Post
 5:      1        30   1      15.0  0 83398.77  6.507      1531 153    Post

 print(output[1])
 [[1]]
     Button Intensity Acc Intensity RT     Time tdelta SubjectID CoupleID PrePost
  1:      0        30   0       0.0  0 77987.93  0.000      1531 153 Pre
  2:      1        30   1      13.5  0 78084.57 96.639      1531 153 Pre
  3:      1        30   1      15.0  0 78098.62 14.054      1531 153 Pre
  4:      1        30   1       6.0  0 78114.13 15.508      1531 153 Pre
  5:      1        30   1      15.0  0 78120.67  6.537      1531 153 Pre

我想将它们组合成一个具有以下逻辑和格式的大数据框:

SubjectID  CoupleID  PrePost  Miss1RT   Miss2RT Miss3RT Hit1RT   Hit2RT  Hit3RT
1531    153          Post     0.00       NA     NA      NA     36.78    14.027
1531    153          Pre      0.00       NA     NA      NA     96.638   14.054

如果 Button == 0,则为 Miss,如果 ==1,则为 Hit。所以,它应该是这样的:

for row in output[i].rows:
   if Button ==0:
      Miss1RT ==tdelta
   elif Button ==1;
      Miss1RT =='NA'

然后是翻转版本,如果 Button 为 1,则 Hit[i]RT 为 tdelta,否则为“NA”。

每个数据帧有 26 行,每一行是命中或未命中,因此将有 26 个未命中列和 26 个命中列,每个 SubjectID 有两行 - 一行用于 Pre,一行用于 Post。所以最终输出的列标题将是:

SubjectID  CoupleID  PrePost  Miss1RT   Miss2RT ...Miss26RT  Hit1RT  Hit2RT ... Hit26RT

我是 R 新手,正在努力学习正确的语法。

【问题讨论】:

  • 你只想看前两个Hits和Misses吗?或者你想看看所有可能的? IE。您想为您的Post、CoupleID = 153 使用Hit2RT = 15.585 吗?
  • 我想要 Hit1-26RT 和 Miss1-26RT 的每个 Pre/Post SubjectID 相同,以便 26 Button==1 或 0 行中的每一个在 Hit[i]RT 或Miss[i]RT 和另一个中的“NA”。为了清楚起见,编辑了帖子。
  • 那么Hit1RT 应该是NA 吗?然后Hit2RT 成为36.78?
  • facepalm 是的。让我解决这个问题。

标签: r csv dataframe data-processing


【解决方案1】:

这样的事情应该可以工作:

#Get data in structure OP has
output <- list(pre, post)
output2 <- lapply(output, function(x) cbind(x, num = paste0(1:nrow(x), "RT")))
pre_post <- do.call("rbind", output2)

#Perform actual calculations
pre_post$miss <- ifelse(pre_post$Button == 0, pre_post$tdelta, NA)
pre_post$hit <- ifelse(pre_post$Button == 1, pre_post$tdelta, NA)

pre_post_melted <- melt(pre_post, id.vars = c("SubjectID", "CoupleID", "num", "PrePost"), measure.vars = c("hit","miss"))
pre_post_res <- dcast(pre_post_melted, SubjectID + CoupleID + PrePost ~ variable + num, sep = "")

pre_post_res

  #SubjectID CoupleID PrePost hit_1RT hit_2RT hit_3RT hit_4RT hit_5RT miss_1RT miss_2RT miss_3RT miss_4RT miss_5RT
#1      1531      153    Post      NA  36.782  14.027  15.585   6.507        0       NA       NA       NA       NA
#2      1531      153     Pre      NA  96.639  14.054  15.508   6.537        0       NA       NA       NA       NA

我们转置数据以动态创建我们想要的所有变量。我们还堆叠数据以避免重复步骤。


数据:

pre <- structure(list(Button = c(0L, 1L, 1L, 1L, 1L), Intensity = c(30L, 
30L, 30L, 30L, 30L), Acc = c(0L, 1L, 1L, 1L, 1L), Intensity = c(0, 
13.5, 15, 6, 15), RT = c(0L, 0L, 0L, 0L, 0L), Time = c(77987.93, 
78084.57, 78098.62, 78114.13, 78120.67), tdelta = c(0, 96.639, 
14.054, 15.508, 6.537), SubjectID = c(1531L, 1531L, 1531L, 1531L, 
1531L), CoupleID = c(153L, 153L, 153L, 153L, 153L), PrePost = c("Pre", 
"Pre", "Pre", "Pre", "Pre")), .Names = c("Button", "Intensity", 
"Acc", "Intensity", "RT", "Time", "tdelta", "SubjectID", "CoupleID", 
"PrePost"), row.names = c(NA, -5L), class = "data.frame")

post <- structure(list(Button = c(0L, 1L, 1L, 1L, 1L), Intensity = c(30L, 
30L, 30L, 30L, 30L), Acc = c(0L, 1L, 1L, 1L, 1L), Intensity = c(0, 
13.5, 15, 6, 15), RT = c(0L, 0L, 0L, 0L, 0L), Time = c(83325.87, 
83362.65, 83376.68, 83392.27, 83398.77), tdelta = c(0, 36.782, 
14.027, 15.585, 6.507), SubjectID = c(1531L, 1531L, 1531L, 1531L, 
1531L), CoupleID = c(153L, 153L, 153L, 153L, 153L), PrePost = c("Post", 
"Post", "Post", "Post", "Post")), .Names = c("Button", "Intensity", 
"Acc", "Intensity", "RT", "Time", "tdelta", "SubjectID", "CoupleID", 
"PrePost"), row.names = c(NA, -5L), class = "data.frame")

【讨论】:

  • 看起来第一步是合并数据帧的“前”和“后”列表,但它们都只是在一个数据帧列表中,“输出”。当我尝试output$miss &lt;- ifelse(output$Button == 0, output$tdelta, NA) output$hit &lt;- ifelse(output$Button == 1, output$tdelta, NA) 时,它没有给我任何错误,但似乎没有改变任何东西。 pre_post_melted &lt;- melt(output, id.vars = c("SubjectID", "CoupleID", "num", "PrePost"), measure.vars = c("hit","miss")) Error in melt.data.table(X[[i]], ...) : One or more values in 'id.vars' is invalid.
  • @HeatherCohen 那是因为听起来output 是一个列表。尝试堆叠output$pre 和output$post
  • 或者在您的案例堆栈中 output[[1]] 和 output[[2]]
  • 由于output列表中有13个数据框,以后可能会更多,所以我把它改成:df &lt;- do.call("rbind", output) df$miss &lt;- ifelse(df$Button == 0, df$tdelta, NA) df$hit &lt;- ifelse(df$Button == 1, df$tdelta, NA)melted行之后,我得到这个错误Error in melt.data.table(df, id.vars = c("SubjectID", "CoupleID", "num", : One or more values in 'id.vars' is invalid.
  • 那是因为您需要num 列。您可以使用lapply(output, function(x) cbind(x, num = paste0(1:nrow(x), "RT"))) 在列表中的每个数据框上创建它
猜你喜欢
  • 2022-06-11
  • 2011-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多