我已将长格式的data.frame转换为width,以便将其与另一个数据框合并。当我将多边型转换为宽型时,我得到了很多NA,我想消除这些NA,并使用现有数据创建一些新列。
对于相同的ID,长数据可以具有多个级别。我希望所有级别都采用较宽的格式,而不是较长的格式。因为我的长数据有40多个级别,所以当我使用“ dcast”将其转换为宽级别时,我会得到很多带有大量NA的列。我尝试了许多方法来合并这些列,以消除尽可能多的NA,但这是行不通的。
我的数据如下:
ID | Date | Gender | Age | Name1 | Name2 | Name3 | Name4 | ... | NameN |
----------------------------------------------------------------------
1 1/1 F 1 NA Name2 Name3 NA NameN
2 2/2 M 2 NA NA Name3 NA NA
3 3/3 F 3 NA Name2 Name3 NA NA
4 4/4 F 4 Name1 NA Name3 NA NA
5 5/5 F 5 NA NA NA Name4 NA
6 6/6 M 6 NA NA NA NA NA
7 7/7 F 7 NA NA NA NA NA
8 8/8 F 8 NA NA NA NA NA
我想得到类似这样的东西
ID | Date | Gender | Age | Risk1 | Risk2| ...| RiskN |
------------------------------------------------------
1 1/1 F 1 Name2 Name3 NameN
2 2/2 M 2 Name3 NA NA
3 3/3 F 3 Name2 Name3 NA
4 4/4 F 4 Name1 Name3 NA
5 5/5 F 5 Name4 NA NA
6 6/6 M 6 NA NA NA
7 7/7 F 7 NA NA NA
8 8/8 F 8 NA NA NA
Edit1:感谢您的回答,不幸的是,它们都没有提供预期的输出。我编辑了上面的数据,以包括我的数据中另外一些条目,这些条目将被完全排除在外。我也有45个变量(Name1,Name2 ... Name45)。根据我收到的第二个答案,我应该只剩下9个Risk变量。抱歉造成混乱!
第一个答案的输出是消除所有类似于6:8行的行。另外,其余数据看起来与上面的预期不同,但更像是:
ID | Date | Gender | Age | RiskName1 | RiskName2 | RiskName3 | RiskName4 | ... | RiskNameN
------------------------------------------------------------------------------------------
4 4/4 F 4 Name1 NA Name3 NA NA
1 1/1 F 1 NA Name2 Name3 NA NameN
3 3/3 F 3 NA Name2 Name3 NA NA
2 2/2 M 2 NA NA Name3 NA NA
5 5/5 F 5 NA NA NA Name4 NA
第二个答案仍然消除了类似于6:8的数据,但是在实际上消除了现有的大量列方面表现更好,但是它用数字代替了所有行内容。例如
ID | Date | Gender | Age | Risk1 | Risk2| Risk3 |
-------------------------------------------------
1 1/1 F 1 1 1 1
2 2/2 M 2 1 0 0
3 3/3 F 3 1 1 0
4 4/4 F 4 1 1 0
5 5/5 F 5 1 0 0
Edit2: 数据很敏感,但是我创建了一个非常相似的结构供您使用。谢谢!
样本数据:
structure(list(Ref = c("213", "42", "512", "123","421"),
Start = structure(c(1541912880, 1541912880, 1541918160,1541918160,1542024180), class = c("POSIXct", "POSIXt"), tzone = "UTC"),Age = c(1, 7, 8, 6, 3),
Gender = c("Female", "Male", "Female","Female", "Female"), Ethnicity = c("E2", "E1", "E4", "E1", "E1"), Cats = c("cats", "cats", NA_character_,NA_character_, NA_character_), Dogs = c(NA_character_,NA_character_, NA_character_, "dogs", NA_character_), Iguanas = c(NA_character_, "Iguanas", NA_character_, "Iguanas", NA_character_), Coalas = c(NA_character_, NA_character_, NA_character_, NA_character_, NA_character_), Ducks = c("ducks", NA_character_,"ducks",NA_character_, NA_character_)), row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame"))
我希望它看起来如何:
Ref | Date | Gender | Age | Risk1 | Risk2| Risk3 |
---------------------------------------------------------
213 2018-11-11 F 1 cats ducks NA
42 2018-11-11 M 7 cats Iguanas NA
512 2018-11-11 F 8 ducks NA NA
123 2018-11-11 F 6 dogs Iguanas NA
421 2018-11-12 F 3 NA NA NA
答案 0 :(得分:3)
一个选项是将“名称”列gather
转换为“长”格式,同时用NA
删除na.rm = TRUE
,然后按“ ID”分组,将“风险”创建为序列列,然后spread
回到“宽”格式
library(tidyverse)
gather(df1, Risk, val, starts_with("Name"), na.rm = TRUE) %>%
group_by(ID) %>%
mutate(Risk = str_c("Risk", Risk)) %>%
spread(Risk, val)
使用新的更新数据集
df2 %>%
gather(Risk, val, Cats:Ducks) %>%
mutate(Ref = factor(Ref, levels = unique(Ref))) %>%
arrange(Ref, is.na(val)) %>%
group_by(Ref) %>%
slice(if(all(is.na(val))) 1 else which(!is.na(val))) %>%
mutate(Risk = str_c('Risk', row_number())) %>%
spread(Risk, val)
# A tibble: 5 x 7
# Groups: Ref [5]
# Ref Start Age Gender Ethnicity Risk1 Risk2
# <fct> <dttm> <dbl> <chr> <chr> <chr> <chr>
#1 213 2018-11-11 05:08:00 1 Female E2 cats ducks
#2 42 2018-11-11 05:08:00 7 Male E1 cats Iguanas
#3 512 2018-11-11 06:36:00 8 Female E4 ducks <NA>
#4 123 2018-11-11 06:36:00 6 Female E1 dogs Iguanas
#5 421 2018-11-12 12:03:00 3 Female E1 <NA> <NA>
答案 1 :(得分:2)
使用data.table类似的转换为长距离然后返回宽距离的方法
library(data.table)
setDT(df)
long <- melt(df, which(!names(df) %like% 'Name'), na.rm = T)
dcast(long[, -'variable'], ... ~ paste0('Risk', rowid(ID)))
# Date Gender Age Risk1 Risk2
# 1: 1/1 F 1 Name2 Name3
# 2: 2/2 M 2 Name3 <NA>
# 3: 3/3 F 3 Name2 Name3
# 4: 4/4 F 4 Name1 Name3
# 5: 5/5 F 5 Name4 <NA>
使用的数据:
df <- fread('
ID Date Gender Age Name1 Name2 Name3 Name4
1 1/1 F 1 NA Name2 Name3 NA
2 2/2 M 2 NA NA Name3 NA
3 3/3 F 3 NA Name2 Name3 NA
4 4/4 F 4 Name1 NA Name3 NA
5 5/5 F 5 NA NA NA Name4
')