R代码使用最后一列对齐所有行的长度
R code to use last column to align all rows length
我有一个非常复杂和庞大的数据框,我需要在 R 中进行数据整理。我无法想出任何可能在 R 中使用的方法,因此我们将不胜感激。
我的数据框中的示例如下所示:
原始数据
现在数据要这样整理完了。我想通过使用列'v8'来移动所有行来对齐
需要这样做
对于NA,原始数据中有一些NA,它们都属于特定变量。
它们只能被视为价值观。
有人可以帮忙吗?
将不胜感激!!
您可以使用快速而肮脏的循环来实现此目的(但这可能效率低下,具体取决于数据集的大小)。
循环的第一级遍历每一行,并检查最后一列是否包含 NA 值 - 如果是,则将所有内容都滑动一个。多次重复此操作,以防数据集末尾有很多列 NA 并且需要滑过很长一段路(使用循环的第二级对数据集中的每一列迭代一次;n-1 次迭代是够了)。
# Dataset
dat <- data.frame(v1 = c(12, NA, 22, NA, NA),
v3 = c(56, 78, 78, NA, 4),
v7 = c(NA, 52, 32, NA, 9),
v8 = c(98, NA, NA, NA, NA))
# Iterate over every row of the dataaset
for(i in 1:nrow(dat)){
# Iterate once for every column in the dataset.
for(j in 1:(length(dat)-1)){
# if the final column for that row is NA, slide everything over by one.
if(is.na(dat[i, length(dat)])){
dat[i,] <- c(NA, dat[i,][-length(dat)])
}
}
}
坦率地说,那不应该是 data.frame
,而应该是 matrix
:在框架中,每一列都表示一些有意义的东西,并且可能与相邻的列不同;在这张数据图片中,出现整数的 absolute 列似乎没有多大意义,即使相对位置(在一行内)具有意义。我建议你转换成一个矩阵,不要再把它当作一个框架。
df <- data.frame(
v1=c(12,NA,22),
v2=c(34,45,88),
v3=c(56,78,78),
v4=c(78,NA,NA),
v5=c(NA,NA,NA_real_),
v6=c(NA,43,67),
v7=c(NA,52,32),
v8=c(98,NA,NA))
mtx <- as.matrix(df)
t(apply(mtx, 1, function(r) {
tailna <- rev(cumsum(!is.na(rev(r))) == 0L)
c(r[tailna], r[!tailna])
}))
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
# [1,] 12 34 56 78 NA NA NA 98
# [2,] NA NA 45 78 NA NA 43 52
# [3,] NA 22 88 78 NA NA 67 32
但是,如果您绝对必须将其作为框架,只需执行此操作,然后再将其转换回来。
您还可以这样做:
library(tidyr)
library(dplyr)
library(stringr)
df <- data.frame(
v1=c(12,NA,22,NA),
v2=c(34,45,88,75),
v3=c(56,78,78,NA),
v4=c(78,NA,NA,44),
v5=c(NA,NA,NA,NA),
v6=c(NA,43,67,6),
v7=c(NA,52,32,NA),
v8=c(98,NA,NA,NA))
cols <- ncol(df)
df %>%
unite("id") %>%
mutate(id2 = gsub("(_NA)*$", "", id)) %>%
mutate(del_count = cols - 1 - str_count(id2, "_")) %>%
transmute(col = paste0(strrep("_", del_count), id2)) %>%
separate(col, paste0("V", 1:cols), "_")
V1 V2 V3 V4 V5 V6 V7 V8
1 12 34 56 78 NA NA NA 98
2 NA 45 78 NA NA 43 52
3 22 88 78 NA NA 67 32
4 NA 75 NA 44 NA 6
它为所有变量创建连接字符串,然后删除最后重复的 NA
s,然后用 '_'
分隔符填充,然后用于拆分列。
我有一个非常复杂和庞大的数据框,我需要在 R 中进行数据整理。我无法想出任何可能在 R 中使用的方法,因此我们将不胜感激。
我的数据框中的示例如下所示:
原始数据
现在数据要这样整理完了。我想通过使用列'v8'来移动所有行来对齐
需要这样做
对于NA,原始数据中有一些NA,它们都属于特定变量。 它们只能被视为价值观。
有人可以帮忙吗? 将不胜感激!!
您可以使用快速而肮脏的循环来实现此目的(但这可能效率低下,具体取决于数据集的大小)。
循环的第一级遍历每一行,并检查最后一列是否包含 NA 值 - 如果是,则将所有内容都滑动一个。多次重复此操作,以防数据集末尾有很多列 NA 并且需要滑过很长一段路(使用循环的第二级对数据集中的每一列迭代一次;n-1 次迭代是够了)。
# Dataset
dat <- data.frame(v1 = c(12, NA, 22, NA, NA),
v3 = c(56, 78, 78, NA, 4),
v7 = c(NA, 52, 32, NA, 9),
v8 = c(98, NA, NA, NA, NA))
# Iterate over every row of the dataaset
for(i in 1:nrow(dat)){
# Iterate once for every column in the dataset.
for(j in 1:(length(dat)-1)){
# if the final column for that row is NA, slide everything over by one.
if(is.na(dat[i, length(dat)])){
dat[i,] <- c(NA, dat[i,][-length(dat)])
}
}
}
坦率地说,那不应该是 data.frame
,而应该是 matrix
:在框架中,每一列都表示一些有意义的东西,并且可能与相邻的列不同;在这张数据图片中,出现整数的 absolute 列似乎没有多大意义,即使相对位置(在一行内)具有意义。我建议你转换成一个矩阵,不要再把它当作一个框架。
df <- data.frame(
v1=c(12,NA,22),
v2=c(34,45,88),
v3=c(56,78,78),
v4=c(78,NA,NA),
v5=c(NA,NA,NA_real_),
v6=c(NA,43,67),
v7=c(NA,52,32),
v8=c(98,NA,NA))
mtx <- as.matrix(df)
t(apply(mtx, 1, function(r) {
tailna <- rev(cumsum(!is.na(rev(r))) == 0L)
c(r[tailna], r[!tailna])
}))
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
# [1,] 12 34 56 78 NA NA NA 98
# [2,] NA NA 45 78 NA NA 43 52
# [3,] NA 22 88 78 NA NA 67 32
但是,如果您绝对必须将其作为框架,只需执行此操作,然后再将其转换回来。
您还可以这样做:
library(tidyr)
library(dplyr)
library(stringr)
df <- data.frame(
v1=c(12,NA,22,NA),
v2=c(34,45,88,75),
v3=c(56,78,78,NA),
v4=c(78,NA,NA,44),
v5=c(NA,NA,NA,NA),
v6=c(NA,43,67,6),
v7=c(NA,52,32,NA),
v8=c(98,NA,NA,NA))
cols <- ncol(df)
df %>%
unite("id") %>%
mutate(id2 = gsub("(_NA)*$", "", id)) %>%
mutate(del_count = cols - 1 - str_count(id2, "_")) %>%
transmute(col = paste0(strrep("_", del_count), id2)) %>%
separate(col, paste0("V", 1:cols), "_")
V1 V2 V3 V4 V5 V6 V7 V8
1 12 34 56 78 NA NA NA 98
2 NA 45 78 NA NA 43 52
3 22 88 78 NA NA 67 32
4 NA 75 NA 44 NA 6
它为所有变量创建连接字符串,然后删除最后重复的 NA
s,然后用 '_'
分隔符填充,然后用于拆分列。