将值与 R 中的相应列匹配
Matching values to corresponding columns in R
我在 R 中有一个数据框需要清理。问题是数据在值内有相应的列名(在引号内;它对应于列名)。然后我只想将数值保留在 :
.
的右侧
这是原始数据框:
> df
col1 col2 col3 col4
1 "4":50 "2":10 "1":0 "3":20
2 "2":5 "4":-50
3 NULL
4 "4":65 "3":45 "2":-15 "1":0
期望的输出:
> new_df
col1 col2 col3 col4
1 0 10 20 50
2 0 5 0 -50
3 NULL
4 0 -15 45 65
为方便起见,这里是 dput(df)
.
的输出
dput(df)
structure(list(`1` = c("\"4\":50", "\"2\":5", "NULL", "\"4\":65"
), `2` = c("\"2\":10", "\"4\":-50", "", "\"3\":45"), `3` = c("\"1\":0",
"", "", "\"2\":-15"), `4` = c("\"3\":20", "", "", "\"1\":0")), class = "data.frame", row.names = c(NA,
-4L))
这是一个尽可能接近该数据的数据框。所有行都需要有一个值或一个 NA,所以第三行有:
3 "NULL" "" "" ""
需要特殊处理引号和分隔符,因为使用 read.table
:
不容易输入数据排列
df <- read.table(text=' col1, col2, col3, col4
1, "4":50 , "2":10 , "1":0, "3":20
2, "2":5, "4":-50
3, NULL
4 , "4":65, "3":45, "2":-15, "1":0', sep=",", header=TRUE,quote="\"",fill=TRUE,strip.white=TRUE)
现在可以分别处理每一行并将值定位在键的位置:
我的第一次尝试是:
df2 <- apply(df, 1, function(x) if(x=="NULL"){ c("NULL",NA,NA,NA) } else
{ z <- rep(0,4)
for (i in x){
z[as.numeric(sub( ":.+$", "", i))] <- sub("^.+:", "", i) }
return(z)})
从侧面看几乎是正确的。由于 R returns 由 apply
以 "column-major" 排列产生,因此您经常需要转置:
df3 <- t(df2)
df3
[,1] [,2] [,3] [,4]
1 "0" "10" "20" "50"
2 "0" "5" "0" "-50"
3 "NULL" NA NA NA
4 "0" "-15" "45" "65"
@Z.Springirth:请不要抱怨这些是字符值。您是在此输出中指定 a"NULL" 值的人。 "NULL" 不是合法的数值,数据框中的列必须相同 class。因此,一列中的一个字符值强制所有值都是字符。
这让您看起来很成功,但我警告您,列是因素而不是字符。这些条目不会表现得像数字,除非您将它们(单独)强制为数字:
> as.data.frame(df3)
V1 V2 V3 V4
1 0 10 20 50
2 0 5 0 -50
3 NULL <NA> <NA> <NA>
4 0 -15 45 65
如果您愿意放弃 "NULL" 要求,那么这可能会完成整个过程:
> df4 <- as.data.frame(df3,stringsAsFactors=FALSE)
> df4[] <- lapply(df4, as.numeric)
Warning message:
In lapply(df4, as.numeric) : NAs introduced by coercion
> df4
V1 V2 V3 V4
1 0 10 20 50
2 0 5 0 -50
3 NA NA NA NA
4 0 -15 45 65
我在 R 中有一个数据框需要清理。问题是数据在值内有相应的列名(在引号内;它对应于列名)。然后我只想将数值保留在 :
.
这是原始数据框:
> df
col1 col2 col3 col4
1 "4":50 "2":10 "1":0 "3":20
2 "2":5 "4":-50
3 NULL
4 "4":65 "3":45 "2":-15 "1":0
期望的输出:
> new_df
col1 col2 col3 col4
1 0 10 20 50
2 0 5 0 -50
3 NULL
4 0 -15 45 65
为方便起见,这里是 dput(df)
.
dput(df)
structure(list(`1` = c("\"4\":50", "\"2\":5", "NULL", "\"4\":65"
), `2` = c("\"2\":10", "\"4\":-50", "", "\"3\":45"), `3` = c("\"1\":0",
"", "", "\"2\":-15"), `4` = c("\"3\":20", "", "", "\"1\":0")), class = "data.frame", row.names = c(NA,
-4L))
这是一个尽可能接近该数据的数据框。所有行都需要有一个值或一个 NA,所以第三行有:
3 "NULL" "" "" ""
需要特殊处理引号和分隔符,因为使用 read.table
:
df <- read.table(text=' col1, col2, col3, col4
1, "4":50 , "2":10 , "1":0, "3":20
2, "2":5, "4":-50
3, NULL
4 , "4":65, "3":45, "2":-15, "1":0', sep=",", header=TRUE,quote="\"",fill=TRUE,strip.white=TRUE)
现在可以分别处理每一行并将值定位在键的位置:
我的第一次尝试是:
df2 <- apply(df, 1, function(x) if(x=="NULL"){ c("NULL",NA,NA,NA) } else
{ z <- rep(0,4)
for (i in x){
z[as.numeric(sub( ":.+$", "", i))] <- sub("^.+:", "", i) }
return(z)})
从侧面看几乎是正确的。由于 R returns 由 apply
以 "column-major" 排列产生,因此您经常需要转置:
df3 <- t(df2)
df3
[,1] [,2] [,3] [,4]
1 "0" "10" "20" "50"
2 "0" "5" "0" "-50"
3 "NULL" NA NA NA
4 "0" "-15" "45" "65"
@Z.Springirth:请不要抱怨这些是字符值。您是在此输出中指定 a"NULL" 值的人。 "NULL" 不是合法的数值,数据框中的列必须相同 class。因此,一列中的一个字符值强制所有值都是字符。
这让您看起来很成功,但我警告您,列是因素而不是字符。这些条目不会表现得像数字,除非您将它们(单独)强制为数字:
> as.data.frame(df3)
V1 V2 V3 V4
1 0 10 20 50
2 0 5 0 -50
3 NULL <NA> <NA> <NA>
4 0 -15 45 65
如果您愿意放弃 "NULL" 要求,那么这可能会完成整个过程:
> df4 <- as.data.frame(df3,stringsAsFactors=FALSE)
> df4[] <- lapply(df4, as.numeric)
Warning message:
In lapply(df4, as.numeric) : NAs introduced by coercion
> df4
V1 V2 V3 V4
1 0 10 20 50
2 0 5 0 -50
3 NA NA NA NA
4 0 -15 45 65