在R中操纵数据框

时间:2016-08-15 00:49:27

标签: python r

我试图将以下数据框中的数据粘贴到其后的数据框中,其中B列和C列中的值组合为D中的值的列名,按A中的值分组。

以下是可重现的例子。

set.seed(10)

fooDF <- data.frame(A = sample(1:4, 10, replace=TRUE), B = sample(letters[1:4], 10, replace=TRUE), C= sample(letters[1:4], 10, replace=TRUE), D = sample(1:4, 10, replace=TRUE))
fooDF[!duplicated(fooDF),]

   A B C D
1  4 c b 2
2  4 d a 2
3  2 a b 4
4  3 c a 1
5  4 a b 3
6  4 b a 2
7  1 b d 2
8  1 a d 4
9  2 b a 3
10 2 d c 2

newdata <- data.frame(A = 1:4)
for(i in 1:nrow(fooDF)){
    col_name <- paste(fooDF$B[i], fooDF$C[i], sep="")
    newdata[newdata$A == fooDF$A[i], col_name ] <- fooDF$D[i]


}

我想要的格式。

> newdata
  A cb da ab ca ba bd ad dc
1 1 NA NA NA NA NA  2  4 NA
2 2 NA NA  4 NA  3 NA NA  2
3 3 NA NA NA  1 NA NA NA NA
4 4  2  2  3 NA  2 NA NA NA

现在我正在逐行进行,但对于包含500万行的大型csv而言,这是不可行的。有没有办法在R或python中更快地完成它?

2 个答案:

答案 0 :(得分:3)

首先将B和C列粘贴在一起(进入#34; z&#34;列):

fooDF$z = paste0(fooDF$B,fooDF$C)

   A B C D  z
1  3 d c 3 dc
2  1 b d 3 bd
3  1 a a 2 aa
4  2 d a 1 da
5  4 d c 1 dc
6  2 d b 2 db
7  4 b d 3 bd
8  2 c d 3 cd
9  1 a b 2 ab
10 4 a b 2 ab

然后我将删除B和C列

fooDF$B = NULL
fooDF$c = NULL

最后从长到宽重塑:

finalFooDF = reshape(fooDF, timevar = "z", direction = "wide",idvar = "A")

  A D.dc D.bd D.aa D.da D.db D.cd D.ab
1 3    3   NA   NA   NA   NA   NA   NA
2 1   NA    3    2   NA   NA   NA    2
4 2   NA   NA   NA    1    2    3   NA
5 4    1    3   NA   NA   NA   NA    2

答案 1 :(得分:3)

R中,可以使用tidyr

完成此操作
library(tidyr)
fooDF %>%
     unite(BC, B, C, sep="")  %>%
     spread(BC, D)
#  A ab ad ba bd ca cb da dc
#1 1 NA  4 NA  2 NA NA NA NA
#2 2  4 NA  3 NA NA NA NA  2
#3 3 NA NA NA NA  1 NA NA NA
#4 4  3 NA  2 NA NA  2  2 NA

或者我们可以使用dcast

执行此操作
library(data.table)
dcast(setDT(fooDF), A~paste0(B,C), value.var = "D")
#    A ab ad ba bd ca cb da dc
#1: 1 NA  4 NA  2 NA NA NA NA
#2: 2  4 NA  3 NA NA NA NA  2
#3: 3 NA NA NA NA  1 NA NA NA
#4: 4  3 NA  2 NA NA  2  2 NA

数据

fooDF <- structure(list(A = c(4L, 4L, 2L, 3L, 4L, 4L, 1L, 1L, 2L, 2L), 
B = c("c", "d", "a", "c", "a", "b", "b", "a", "b", "d"), 
C = c("b", "a", "b", "a", "b", "a", "d", "d", "a", "c"), 
D = c(2L, 2L, 4L, 1L, 3L, 2L, 2L, 4L, 3L, 2L)), .Names = c("A", 
"B", "C", "D"), class = "data.frame", row.names = c("1", "2", 
"3", "4", "5", "6", "7", "8", "9", "10"))