将长数据转换为宽数据并在 R 中计算总和
convert long data to wide and calculate sum in R
如何将长数据重塑为宽数据
x = c('x1','x1','x2','x2')
y = c('y1','y1','y2','y2')
z= c('a','b','a','b')
n = c(3,5,7,2)
df1 <- data.table(x,y,z,n)
> df1
x y z n
1: x1 y1 a 3
2: x1 y1 b 5
3: x2 y2 a 7
4: x2 y2 b 2
以宽格式获得如下所示的输出。其中我按 x 和 y 列分组,将 z 列按行分布并计算 n 列的总和。
x y z n z.1 z.2
1: x1 y1 a 8 a b
2: x2 y2 b 9 a b
我试过使用 reshape 和 dcast,但对我没有帮助
dcast(df1, x ~ y, value.var="value")
我不清楚为什么需要 z、z.1 和 z.2。在输出 table 中,它在上述要求的输出示例中为您提供了什么信息?
我在这里的解决方案可能会有所帮助,这也会捕获 z 值,为您提供有关哪个值具有 id a
或 id b
的信息
df1 <- data.table(x,y,z,n)
df1$id <- c(as.factor(df1$z)) # create an id on z, so that you can capture the info
x y z n id
1: x1 y1 a 3 1
2: x1 y1 b 5 2
3: x2 y2 a 7 1
4: x2 y2 b 2 2
# reshape with the id var to wide format
dt <- reshape(df1,timevar= "id", idvar = c("x","y"), direction="wide")
x y z.1 n.1 z.2 n.2
1: x1 y1 a 3 b 5
2: x2 y2 a 7 b 2
# finally do a rowsums
dt[, Sum := rowSums(.SD, na.rm = TRUE), .SDcols = grep("n", names(dt))]
dt
x y z.1 n.1 z.2 n.2 Sum
1: x1 y1 a 3 b 5 8
2: x2 y2 a 7 b 2 9
这是 tidyr 的解决方案。
x = c('x1','x1','x2','x2')
y = c('y1','y1','y2','y2')
z= c('a','b','a','b')
n = c(3,5,7,2)
df <- data.frame(x,y,z,n)
library(tidyr)
library(dplyr)
answer<-df %>% group_by(x, y) %>% mutate(n=sum(n)) %>%
unite(title, -3) %>% spread(z, z) %>% separate( title, into=c("x", "y", "n"))
# x y n a b
# <chr> <chr> <chr> <fct> <fct>
# 1 x1 y1 8 a b
# 2 x2 y2 9 a b
我允许 reader 将列调整为所需的格式。
只是把另一个选项扔进锅里(并不是我认为其他解决方案不合适)。我觉得这种方式简单直观。
df1 <- data.frame(x,y,z,n)
data.frame(c(aggregate(n ~ x+y, sum, data=df1),
aggregate(z ~ x+y, unique, data=df1)[3]))
# x y n z.1 z.2
# 1 x1 y1 8 a b
# 2 x2 y2 9 a b
我也省略了 z 列,因为它没有意义,也没有给出决定如何计算它的规范。
这里 unique() 的使用相当随意,它可以是 sort() 或只是 function(z){z}。
如何将长数据重塑为宽数据
x = c('x1','x1','x2','x2')
y = c('y1','y1','y2','y2')
z= c('a','b','a','b')
n = c(3,5,7,2)
df1 <- data.table(x,y,z,n)
> df1
x y z n
1: x1 y1 a 3
2: x1 y1 b 5
3: x2 y2 a 7
4: x2 y2 b 2
以宽格式获得如下所示的输出。其中我按 x 和 y 列分组,将 z 列按行分布并计算 n 列的总和。
x y z n z.1 z.2
1: x1 y1 a 8 a b
2: x2 y2 b 9 a b
我试过使用 reshape 和 dcast,但对我没有帮助
dcast(df1, x ~ y, value.var="value")
我不清楚为什么需要 z、z.1 和 z.2。在输出 table 中,它在上述要求的输出示例中为您提供了什么信息?
我在这里的解决方案可能会有所帮助,这也会捕获 z 值,为您提供有关哪个值具有 id a
或 id b
df1 <- data.table(x,y,z,n)
df1$id <- c(as.factor(df1$z)) # create an id on z, so that you can capture the info
x y z n id
1: x1 y1 a 3 1
2: x1 y1 b 5 2
3: x2 y2 a 7 1
4: x2 y2 b 2 2
# reshape with the id var to wide format
dt <- reshape(df1,timevar= "id", idvar = c("x","y"), direction="wide")
x y z.1 n.1 z.2 n.2
1: x1 y1 a 3 b 5
2: x2 y2 a 7 b 2
# finally do a rowsums
dt[, Sum := rowSums(.SD, na.rm = TRUE), .SDcols = grep("n", names(dt))]
dt
x y z.1 n.1 z.2 n.2 Sum
1: x1 y1 a 3 b 5 8
2: x2 y2 a 7 b 2 9
这是 tidyr 的解决方案。
x = c('x1','x1','x2','x2')
y = c('y1','y1','y2','y2')
z= c('a','b','a','b')
n = c(3,5,7,2)
df <- data.frame(x,y,z,n)
library(tidyr)
library(dplyr)
answer<-df %>% group_by(x, y) %>% mutate(n=sum(n)) %>%
unite(title, -3) %>% spread(z, z) %>% separate( title, into=c("x", "y", "n"))
# x y n a b
# <chr> <chr> <chr> <fct> <fct>
# 1 x1 y1 8 a b
# 2 x2 y2 9 a b
我允许 reader 将列调整为所需的格式。
只是把另一个选项扔进锅里(并不是我认为其他解决方案不合适)。我觉得这种方式简单直观。
df1 <- data.frame(x,y,z,n)
data.frame(c(aggregate(n ~ x+y, sum, data=df1),
aggregate(z ~ x+y, unique, data=df1)[3]))
# x y n z.1 z.2
# 1 x1 y1 8 a b
# 2 x2 y2 9 a b
我也省略了 z 列,因为它没有意义,也没有给出决定如何计算它的规范。
这里 unique() 的使用相当随意,它可以是 sort() 或只是 function(z){z}。