将值与 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