使用mutate_at和sum函数按特定列求和行值?

时间:2016-10-01 00:33:05

标签: r dplyr

我有一个包含问卷数据的数据表,因此第一列是参与者ID,后面是每个问卷的列,其中包含单独的问题。例如,数据表看起来像这样,其中A是一个问卷,B是另一个问卷:

ID A1 A2 A3 B1 B2
1  3  5  3  4  2
2  2  5  2  2  1
3  4  1  3  4  1
4  3  2  3  3  2

我想使用dplyr函数对其进行编码。我无法使用dplyr中的mutate_at查找每个问卷的摘要分数,每个ID。我希望找到问卷A(来自A1A2A3)以及B ...等等的总和。但我的数据表中有很多问卷(ABCD .....等等,所以我的代码现在看起来像:

data %>%
  group_by(ID) %>%
  mutate_at(vars(contains("A")), funs(sum)) %>%
  ungroup()

然而,运行它总是给我一个错误

  

错误:参数

的'type'(字符)无效

我无法理解为什么。当我尝试mutate_each时,会发生同样的事情。我怎么解决这个问题?

2 个答案:

答案 0 :(得分:1)

我认为有一种方法如下。我可以使用mutate_at查看您希望如何使用宽格式数据,但您可能需要在此处选择长格式。这会让你的生活变得轻松。您可以使用meltgather以长格式格式化数据。然后,您想要更改列variable。你想删除数字。最后,您按IDvariable对数据进行分组,然后得到总和。

melt(mydf, id.var = "ID") %>%
mutate(variable = gsub(pattern = "[0-9]+", replacement = "", x = variable)) %>%
group_by(ID, variable) %>%
summarise(total = sum(value))

#     ID variable total
#  <int>    <chr> <int>
#1     1        A    11
#2     1        B     6
#3     2        A     9
#4     2        B     3
#5     3        A     8
#6     3        B     5
#7     4        A     8
#8     4        B     5

DATA

mydf <- structure(list(ID = 1:4, A1 = c(3L, 2L, 4L, 3L), A2 = c(5L, 5L, 
1L, 2L), A3 = c(3L, 2L, 3L, 3L), B1 = c(4L, 2L, 4L, 3L), B2 = c(2L, 
1L, 1L, 2L)), .Names = c("ID", "A1", "A2", "A3", "B1", "B2"), class = "data.frame", row.names = c(NA, 
-4L))

答案 1 :(得分:1)

难以做到的原因是您没有明确编码问卷类型和编号,因此数据并非“整洁”。 Jazzurro的方法是正确的,但在这里我使用tidyr包来与gatherseparate进行此操作。

library(tidyr)
library(dplyr)

data %>% 
gather(test, tot, A1:B2) %>% 
separate(test, into=c("Q", "No"), sep=1) %>%
group_by(ID, Q) %>% summarise(totals=sum(tot))

这样可以避免使用gsub之类的内容。

此外,如果您希望A和B位于不同的列中,则可以将%>% spread(Q, totals)添加到管道的末尾。