简体   繁体   English

R中从列到行的数据转换

[英]Data transformation from columns to rows in r

I have a dataframe in this way 我以这种方式有一个数据框

1954 <- c(a,b,c,d)#names of a person
X2 <- c(5,6,1,2)#their score
1955 <- c(e,f,g,h)
X3 <- c(2,4,6,9)
1956 <- c(j,k,l,m)
X4 <- c(1,3,6,8)

Girls <- data.frame(1954,X2,1955,X3,1956,X4)

Girls dataframe looks something like this 女孩数据框看起来像这样

1954 X2 1955 X3 1956 X4 . . . . . . . na 5 e 2 j 1 . . . . . . . nb 6 f 4 k 3 . . . . . . . . nc 1 g 6 l 6 . . . . . . . . .nd 2 h 9 m 8 . . . . . . . . . n

I would like the data frame to look like this 我希望数据框看起来像这样

`Name score year(#new col)
 a     5   1954
 b     6   1954 
 c     1   1954
 d     2   1954
 e     2   1955
 f     4   1955
 g     6   1955
 h     9   1955
 j     1   1956
 k     3   1956
 l     6   1956
 m     8   1956
 .     .     .
 .     .     .
 n     n     n`

This is for a school project and I am struggling to transform data.Could someone help me out with this? 这是一个学校项目,我正在努力转换数据。有人可以帮我这个忙吗?

I had to do some changes to your code, because column names cannot be numbers. 我必须对您的代码进行一些更改,因为列名不能为数字。 But this should do it: 但这应该做到:

X1954 <- c("a","b","c","d")#names of a person
X2 <- c(5,6,1,2)#their score
X1955 <- c("e","f","g","h")
X3 <- c(2,4,6,9)
X1956 <- c("j","k","l","m")
X4 <- c(1,3,6,8)

Girls <- data.frame(X1954,X2,X1955,X3,X1956,X4, stringsAsFactors = FALSE)

library(tidyr)
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(stringr)
Girls %>% 
  as_tibble() %>% 
  gather(key = "year", value = "Name", X1954, X1955, X1956) %>% 
  mutate(key = paste0(year, Name)) %>% 
  gather(key = "key", value = "score", X2, X3, X4) %>% 
  select(-key) %>% 
  mutate(year = str_extract(year, "[:digit:]+$"))
#> # A tibble: 36 x 3
#>    year  Name  score
#>    <chr> <chr> <dbl>
#>  1 1954  a         5
#>  2 1954  b         6
#>  3 1954  c         1
#>  4 1954  d         2
#>  5 1955  e         5
#>  6 1955  f         6
#>  7 1955  g         1
#>  8 1955  h         2
#>  9 1956  j         5
#> 10 1956  k         6
#> # … with 26 more rows

Good luck with your school project! 祝您的学校项目好运!

Created on 2019-02-09 by the reprex package (v0.2.1) reprex软件包 (v0.2.1)创建于2019-02-09

With no additional packages, you could do: 没有其他软件包,您可以执行以下操作:

setNames(
    cbind(
      stack(Girls[, grep("\\d{4}", names(Girls))]),
      stack(Girls[, grep("^X", names(Girls))])[, 1, drop = F]
      ),
  c("Name", "Year", "Score")
  )

Output: 输出:

   Name Year Score
1     a 1954     5
2     b 1954     6
3     c 1954     1
4     d 1954     2
5     e 1955     2
6     f 1955     4
7     g 1955     6
8     h 1955     9
9     j 1956     1
10    k 1956     3
11    l 1956     6
12    m 1956     8

Note that this required some changes to the code which you used to create an example, as you cannot put directly numbers as column names (they need to be within ``, and also letters need to be quoted). 请注意,这需要对用于创建示例的代码进行一些更改,因为您不能直接将数字用作列名(它们必须在``之内,并且也需要用引号引起来)。

Correct code would be: 正确的代码是:

`1954` <- c("a","b","c","d")
X2 <- c(5,6,1,2)
`1955` <- c("e","f","g","h")
X3 <- c(2,4,6,9)
`1956` <- c("j","k","l","m")
X4 <- c(1,3,6,8)

Girls <- data.frame(`1954`,X2,`1955`,X3,`1956`,X4, 
                    stringsAsFactors = FALSE, check.names = FALSE)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM