根据行值向右移动数据框中的单元格
Shift cells in a data frame to the right based on row values
我正在使用一个数据框,该数据框是从多个制表符分隔的文本文件创建的,这些文本文件作为 tibbles 导入,使用 rbind
连接在一起。这些文件都包含相似的列名称,但由于在创建这些文件时添加了注释,因此在导入时某些值位于错误的列下。我正在尝试将非注释单元格值移动到它们相邻的右列。我无法以任何方式更改原始文件。
初始示例数据帧代码:
df1<-df<-data.frame(
c1=c("A","B","C",1,1,1),
c2=c(1,1,1,5,NA,5),
c3=c(5,5,5,"C","C","C"),
c4=c("C","C","C",NA,NA,NA)
)
df2<-data.frame(
c1=c("A","B","F",2,2,2),
c2=c(2,2,2,6,6,6),
c3=c(6,6,6,"D","D","D"),
c4=c("D","D","D",NA,NA,NA)
)
初始示例数据帧:
> df1
c1 c2 c3 c4
1 A 1 5 C
2 B 1 5 C
3 C 1 5 C
4 1 5 C <NA>
5 1 NA C <NA>
6 1 5 C <NA>
> df2
c1 c2 c3 c4
1 A 2 6 D
2 B 2 6 D
3 F 2 6 D
4 2 NA D <NA>
5 2 6 D <NA>
6 2 6 D <NA>
编译数据帧代码:
df<-rbind(df1,df2)
编译数据帧:
> df
c1 c2 c3 c4
1 A 1 5 C
2 B 1 5 C
3 C 1 5 C
4 1 5 C <NA>
5 1 NA C <NA>
6 1 5 C <NA>
7 A 2 6 D
8 B 2 6 D
9 F 2 6 D
10 2 NA D <NA>
11 2 6 D <NA>
12 2 6 D <NA>
所需的数据帧:
c1 c2 c3 c4
1 A 1 5 C
2 B 1 5 C
3 C 1 5 C
4 <NA> 1 5 C
5 <NA> 1 NA C
6 <NA> 1 5 C
7 A 2 6 D
8 B 2 6 D
9 D 2 6 D
10 <NA> 2 NA D
11 <NA> 2 6 D
12 <NA> 2 6 D
第一列中要移动的注释和重复行并不总是相同的长度或相同的值,也不总是数字。
我试过使用类似问题的修改版本来改变我的价值观。
df[]<-t(apply(df, 1, function(x) c(x[is.na(x)], x[!is.na(x)])))
但是此代码使用所有 NA
值并且某些列包含 NA
值,因此这仅在最后一列为 NA
而不是任何其他列时有效。
> df
c1 c2 c3 c4
1 A 1 5 C
2 B 1 5 C
3 C 1 5 C
4 <NA> 1 5 C
5 <NA> <NA> 1 C
6 <NA> 1 5 C
7 A 2 6 D
8 B 2 6 D
9 F 2 6 D
10 <NA> <NA> 2 D
11 <NA> 2 6 D
12 <NA> 2 6 D
有没有办法让此代码仅使用最后一列作为指南,将适当的单元格向右移动?
编辑:类似问题 df1
修改后代码的拼写错误更改为 df
。
已更新:这是解决方案。这有点麻烦,但它确实有效。为了保留初始顺序,一个好主意是将索引设置为列并使用它对最终 df 进行排序。稍后,您可以通过 column_to_rownames
或简单地通过 select(df, -c('index'))
将列恢复为索引。有了这个,我希望我回答了这个问题。
df <- rbind(df1,df2)
df <- mutate_all(df, as.character)
df <- rownames_to_column(df, 'index')
df_ok <- filter(df, !is.na(c4))
df_na <- filter(df, is.na(c4))
df_fin <- df_na %>%
select(c4, everything()) %>%
rename(c1 = c4, c2 = c1, c3 = c2, c4 = c3) %>%
rbind(df_ok)
df_fin <- df_fin %>%
mutate(index = as.integer(index)) %>%
arrange(index)
我正在使用一个数据框,该数据框是从多个制表符分隔的文本文件创建的,这些文本文件作为 tibbles 导入,使用 rbind
连接在一起。这些文件都包含相似的列名称,但由于在创建这些文件时添加了注释,因此在导入时某些值位于错误的列下。我正在尝试将非注释单元格值移动到它们相邻的右列。我无法以任何方式更改原始文件。
初始示例数据帧代码:
df1<-df<-data.frame(
c1=c("A","B","C",1,1,1),
c2=c(1,1,1,5,NA,5),
c3=c(5,5,5,"C","C","C"),
c4=c("C","C","C",NA,NA,NA)
)
df2<-data.frame(
c1=c("A","B","F",2,2,2),
c2=c(2,2,2,6,6,6),
c3=c(6,6,6,"D","D","D"),
c4=c("D","D","D",NA,NA,NA)
)
初始示例数据帧:
> df1
c1 c2 c3 c4
1 A 1 5 C
2 B 1 5 C
3 C 1 5 C
4 1 5 C <NA>
5 1 NA C <NA>
6 1 5 C <NA>
> df2
c1 c2 c3 c4
1 A 2 6 D
2 B 2 6 D
3 F 2 6 D
4 2 NA D <NA>
5 2 6 D <NA>
6 2 6 D <NA>
编译数据帧代码:
df<-rbind(df1,df2)
编译数据帧:
> df
c1 c2 c3 c4
1 A 1 5 C
2 B 1 5 C
3 C 1 5 C
4 1 5 C <NA>
5 1 NA C <NA>
6 1 5 C <NA>
7 A 2 6 D
8 B 2 6 D
9 F 2 6 D
10 2 NA D <NA>
11 2 6 D <NA>
12 2 6 D <NA>
所需的数据帧:
c1 c2 c3 c4
1 A 1 5 C
2 B 1 5 C
3 C 1 5 C
4 <NA> 1 5 C
5 <NA> 1 NA C
6 <NA> 1 5 C
7 A 2 6 D
8 B 2 6 D
9 D 2 6 D
10 <NA> 2 NA D
11 <NA> 2 6 D
12 <NA> 2 6 D
第一列中要移动的注释和重复行并不总是相同的长度或相同的值,也不总是数字。
我试过使用类似问题的修改版本来改变我的价值观。
df[]<-t(apply(df, 1, function(x) c(x[is.na(x)], x[!is.na(x)])))
但是此代码使用所有 NA
值并且某些列包含 NA
值,因此这仅在最后一列为 NA
而不是任何其他列时有效。
> df
c1 c2 c3 c4
1 A 1 5 C
2 B 1 5 C
3 C 1 5 C
4 <NA> 1 5 C
5 <NA> <NA> 1 C
6 <NA> 1 5 C
7 A 2 6 D
8 B 2 6 D
9 F 2 6 D
10 <NA> <NA> 2 D
11 <NA> 2 6 D
12 <NA> 2 6 D
有没有办法让此代码仅使用最后一列作为指南,将适当的单元格向右移动?
编辑:类似问题 df1
修改后代码的拼写错误更改为 df
。
已更新:这是解决方案。这有点麻烦,但它确实有效。为了保留初始顺序,一个好主意是将索引设置为列并使用它对最终 df 进行排序。稍后,您可以通过 column_to_rownames
或简单地通过 select(df, -c('index'))
将列恢复为索引。有了这个,我希望我回答了这个问题。
df <- rbind(df1,df2)
df <- mutate_all(df, as.character)
df <- rownames_to_column(df, 'index')
df_ok <- filter(df, !is.na(c4))
df_na <- filter(df, is.na(c4))
df_fin <- df_na %>%
select(c4, everything()) %>%
rename(c1 = c4, c2 = c1, c3 = c2, c4 = c3) %>%
rbind(df_ok)
df_fin <- df_fin %>%
mutate(index = as.integer(index)) %>%
arrange(index)