我有一个数据框,其中有一个循环中重复的行:
v1 v2 v3 v4
Number 1 2 3 5
Index 0 0 0 0
Number.1 1 2 3 5
Index.1 0 0 0 0
Number.2 1 2 3 5
Index.2 0 0 0 0
Number.3 1 2 3 5
Index.3 0 0 0 0
Number.4 1 2 3 5
Index.4 0 0 0 0
Number.5 1 2 3 5
Index.5 0 0 0 0
我想将所有具有“ Number”的行作为值的一行附加在不同的列中
v1 v2 v3 v4 v5 v6 v7 v8
Number 1 2 3 5 1 2 3 5 etc
尽管看起来很简单,但我还没有找到任何简单的方法来做。 我尝试过像这样的dplyr,但没有成功:
df[,rownames(df)%in%(grep("Number*", rownames(df))]
答案 0 :(得分:1)
我们采用转置和连接(c
)来获得vector
i1 <- rownames(df)%in%(grep("Number(\\.\\d)*", rownames(df), value = TRUE))
v1 <- c(t(df[i1, ]))
注意:grep
返回索引,因此无需再次执行%in%
与行名匹配
i2 <- grep("Number(\\.\\d)*", rownames(df))
足以子集化
v2 <- c(t(df[i2, ]))
最好将其作为向量而不是data.frame。如果我们真的需要单行data.frame并具有许多列
as.data.frame.list(v1)
注2:略微更改了模式以匹配.
,后跟数字(如果有)。在OP的代码中,它将检查Number*
,即0或更大的“ r”(尽管它在数据中有效)
答案 1 :(得分:1)
这是一个相当复杂的dplyr
解决方案-在线注释中的解释。
library(tidyverse)
df2 <- df %>%
mutate(row_name = rownames(.)) %>% # Add a new column with the row names
filter(grepl("Number", row_name)) %>% # filter against a match for 'Number'
select(-row_name) %>% # Get rid of that column
t() %>% # Transpose
map(unlist, use.names = F) %>% # Flatten
as.data.frame() %>% # Convert to a df so we can change the row name later
`colnames<-`(paste0("v", seq(1:ncol(.)))) %>% # Add colnames to your format
`rownames<-`("Number") # Add the row name
结果:
v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18
Number 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3