R 多列处理和动态命名新列

R 多列处理和动态命名新列,r,naming,data-cleaning,large-data,R,Naming,Data Cleaning,Large Data,变量被错误地输入到多个列中,例如:“aaa_1”、“aaa_2”和“aaa_3”或“ccc_1”、“ccc_2”和“ccc_3”)。需要创建单个新列(例如“aaa”或“ccc”)。虽然某些变量当前位于单个列中(“hhh_1”),但可能会添加更多列(hhh_2等) 这就是我得到的: aaa_1 <- c(43, 23, 65, NA, 45) aaa_2 <- c(NA, NA, NA, NA, NA) aaa_3 <- c(NA, NA, 92, NA, 82)

变量被错误地输入到多个列中,例如:“aaa_1”、“aaa_2”和“aaa_3”或“ccc_1”、“ccc_2”和“ccc_3”)。需要创建单个新列(例如“aaa”或“ccc”)。虽然某些变量当前位于单个列中(“hhh_1”),但可能会添加更多列(hhh_2等)

这就是我得到的:

aaa_1 <- c(43, 23, 65, NA, 45)  
aaa_2 <- c(NA, NA, NA, NA, NA)    
aaa_3 <- c(NA, NA, 92, NA, 82)  
ccc_1 <- c("fra", NA, "spa", NA, NA)   
ccc_2 <- c(NA, NA, NA, "wez", NA)  
ccc_3 <- c(NA, "ija", NA, "fda", NA)    
ccc_4 <- c(NA, NA, NA, NA, NA)
hhh_1 <- c(183, NA, 198, NA, 182)    
dataf1 <- data.frame(aaa_1,aaa_2,aaa_3,ccc_1,ccc_2, ccc_3,ccc_4,hhh_1)  

aaa_1我们可以尝试使用
splitstackshape

library(splitstackshape)
nm1 <- sub("_\\d+", "", names(dataf1))
tbl <- table(nm1) > 1
merged.stack(dataf1, var.stubs = names(tbl)[tbl], sep="_")
库(splitstackshape)

nm1我们可以尝试使用
splitstackshape

library(splitstackshape)
nm1 <- sub("_\\d+", "", names(dataf1))
tbl <- table(nm1) > 1
merged.stack(dataf1, var.stubs = names(tbl)[tbl], sep="_")
库(splitstackshape)

nm1我不确定您的示例是否正确。例如,在第三行中,您得到了age_1和age_3的值,然后在该行的所需输出NA中

如果我已经理解了您要做的事情,那么将列转置到行,修复它们,然后再转置回来会容易得多。请尝试使用dplyr和tidyr的“tidyverse”作为起点

library(tidyverse)
library(stringr)

age_1 <- c(43, 23, 65, NA, 45)
age_2 <- c(NA, NA, NA, NA, NA)
age_3 <- c(NA, NA, 92, NA, 82)
country_1 <- c("fra", NA, "spa", NA, NA)
country_2 <- c(NA, NA, NA, "wez", NA)
country_3 <- c(NA, "ija", NA, "fda", NA)
country_4 <- c(NA, NA, NA, NA, NA)
hight_1 <- c(183, NA, 198, NA, 182)
dataf1 <- data.frame(age_1,age_2,age_3,country_1,country_2, country_3,country_4,hight_1)

data <- dataf1 %>%
  mutate(row_num = row_number()) %>%   #create a row number to track values
  gather(key, value, -row_num) %>%    #flatten your data
  drop_na() %>%    #drop na rows
  mutate(key = str_replace(key, "_.", "")) %>%   #remove the '_x' part of names
  group_by(row_num) %>%  
  top_n(1) %>%
  spread(key, value)  #pivot back to columns
库(tidyverse)
图书馆(stringr)
年龄1%#删除na行
mutate(key=str_replace(key,“,”)%>%#删除名称的“_x”部分
分组依据(行数,键)%>%
mutate(count=n())%>%#计算每行/键组合的条目数
mutate(value=ifelse(count>1,NA,value))%>%#为具有重复项的行设置NA
下拉菜单()%>%
排列(键,值)%>%#返回到列
选择(-count)#删除'count'变量

我不确定您的示例是否正确。例如,在第三行中,您得到了age_1和age_3的值,然后在该行的所需输出NA中

如果我已经理解了您要做的事情,那么将列转置到行,修复它们,然后再转置回来会容易得多。请尝试使用dplyr和tidyr的“tidyverse”作为起点

library(tidyverse)
library(stringr)

age_1 <- c(43, 23, 65, NA, 45)
age_2 <- c(NA, NA, NA, NA, NA)
age_3 <- c(NA, NA, 92, NA, 82)
country_1 <- c("fra", NA, "spa", NA, NA)
country_2 <- c(NA, NA, NA, "wez", NA)
country_3 <- c(NA, "ija", NA, "fda", NA)
country_4 <- c(NA, NA, NA, NA, NA)
hight_1 <- c(183, NA, 198, NA, 182)
dataf1 <- data.frame(age_1,age_2,age_3,country_1,country_2, country_3,country_4,hight_1)

data <- dataf1 %>%
  mutate(row_num = row_number()) %>%   #create a row number to track values
  gather(key, value, -row_num) %>%    #flatten your data
  drop_na() %>%    #drop na rows
  mutate(key = str_replace(key, "_.", "")) %>%   #remove the '_x' part of names
  group_by(row_num) %>%  
  top_n(1) %>%
  spread(key, value)  #pivot back to columns
库(tidyverse)
图书馆(stringr)
年龄1%#删除na行
mutate(key=str_replace(key,“,”)%>%#删除名称的“_x”部分
分组依据(行数,键)%>%
mutate(count=n())%>%#计算每行/键组合的条目数
mutate(value=ifelse(count>1,NA,value))%>%#为具有重复项的行设置NA
下拉菜单()%>%
排列(键,值)%>%#返回到列
选择(-count)#删除'count'变量

这是一个基本解决方案,即没有软件包

首先定义
get_only
,当给定一个列表时,它会将其转换为data.frame,并将
get_only
应用于每一行。当给定一个向量时,它会返回其中的单个非NA或NA(如果不只有一个)

root
定义为不带后缀的列名

将数据框转换为列列表,按
root
对它们进行分组,并将
get_only
应用于每个这样的组

最后,将结果列表转换为数据帧

get_only <- function(x) UseMethod("get_only")
get_only.list <- function(x) apply(data.frame(x), 1, get_only)
get_only.default <- function(x) if (sum(!is.na(x)) == 1) na.omit(x) else NA

root <- sub("_.*", "", names(dataf1))
as.data.frame(lapply(split(as.list(dataf1), root), FUN = get_only))

get_only这是一个基本解决方案,即没有包

首先定义
get_only
,当给定一个列表时,它会将其转换为data.frame,并将
get_only
应用于每一行。当给定一个向量时,它会返回其中的单个非NA或NA(如果不只有一个)

root
定义为不带后缀的列名

将数据框转换为列列表,按
root
对它们进行分组,并将
get_only
应用于每个这样的组

最后,将结果列表转换为数据帧

get_only <- function(x) UseMethod("get_only")
get_only.list <- function(x) apply(data.frame(x), 1, get_only)
get_only.default <- function(x) if (sum(!is.na(x)) == 1) na.omit(x) else NA

root <- sub("_.*", "", names(dataf1))
as.data.frame(lapply(split(as.list(dataf1), root), FUN = get_only))

get_only我想确保,如果给定的人的年龄同时输入为65(年龄_1)和92(年龄_3),则输出为NA(因为我无法确定哪一个年龄是正确的,我希望能够插补该观察值/行)。谢谢!编辑了以上我的答案。您可以对条目进行计数并删除任何重复的行。我希望确保,如果给定的人的年龄已输入为65(年龄1)和92(年龄3),则输出为NA(因为我无法确定哪个年龄是正确的,我希望能够输入该观察值/行)。谢谢!编辑了上面的答案。您可以计算条目数并删除任何重复的行感谢您如此仔细地解释!感谢您如此仔细地解释!