2014-07-13 61 views
3

我有以下數據幀:分割的多個列中的R

olddf <- structure(list(test = structure(1:6, .Label = c("test1", "test2", 
"test3", "test4", "test5", "test6"), class = "factor"), month0_gp1 = c("163±28", 
"133±20", "177±29", "153±30", "161±31", "159±23"), month0_gp2 = c("122±17", 
"167±20", "146±26", "150±27", "148±33", "161±37"), month1_gp1 = c("157±32", 
"152±37", "151±24", "143±25", "144±29", "126±30"), month1_gp2 = c("181±14", 
"133±34", "152±38", "144±30", "148±20", "137±19"), month3_gp1 = c("139±38", 
"161±39", "166±38", "162±39", "151±38", "155±38"), month3_gp2 = c("151±40", 
"161±33", "137±25", "161±31", "168±30", "147±34")), .Names = c("test", 
"month0_gp1", "month0_gp2", "month1_gp1", "month1_gp2", "month3_gp1", 
"month3_gp2"), row.names = c(NA, 6L), class = "data.frame") 

    test month0_gp1 month0_gp2 month1_gp1 month1_gp2 month3_gp1 month3_gp2 
1 test1  163±28  122±17  157±32  181±14  139±38  151±40 
2 test2  133±20  167±20  152±37  133±34  161±39  161±33 
3 test3  177±29  146±26  151±24  152±38  166±38  137±25 
4 test4  153±30  150±27  143±25  144±30  162±39  161±31 
5 test5  161±31  148±33  144±29  148±20  151±38  168±30 
6 test6  159±23  161±37  126±30  137±19  155±38  147±34 

我不得不2分割列:7到每個2(一個用於均值和其它用於SD):

test month0_gp1_mean month0_gp1_sd month0_gp2_mean month0_gp2_sd month1_gp1_mean month1_gp1_sd .... 

我檢查早期的帖子和使用do.call(rbind...方法:

mydf <- data.frame(do.call(rbind, strsplit(olddf$month0_gp1,'±'))) 

mydf 
    X1 X2 
1 163 28 
2 133 20 
3 177 29 
4 153 30 
5 161 31 
6 159 23 

但是,這一次適用於一列。我如何修改這個以循環2:7列,並將它們組合起來形成一個新的數據框?謝謝你的幫助。

回答

6

首先,得到my cSplit function from this GitHub Gist

其次,拆起來:

cSplit(olddf, 2:ncol(olddf), sep = "±") 
#  test 2_1 2_2 3_1 3_2 4_1 4_2 5_1 5_2 6_1 6_2 7_1 7_2 
# 1: test1 163 28 122 17 157 32 181 14 139 38 151 40 
# 2: test2 133 20 167 20 152 37 133 34 161 39 161 33 
# 3: test3 177 29 146 26 151 24 152 38 166 38 137 25 
# 4: test4 153 30 150 27 143 25 144 30 162 39 161 31 
# 5: test5 161 31 148 33 144 29 148 20 151 38 168 30 
# 6: test6 159 23 161 37 126 30 137 19 155 38 147 34 

如果你想要做在相同的步驟列重命名,嘗試:

Nam <- names(olddf)[2:ncol(olddf)] 
setnames(
    cSplit(olddf, 2:ncol(olddf), sep = "±"), 
    c("test", paste(rep(Nam, each = 2), c("mean", "sd"), sep = "_")))[] 

另一種辦法是看dplyr + tidyr

這是我能想出的最好的,但我不知道這是否是使用這些工具來做到這一點的正確方法....

olddf %>% 
    gather(GM, value, -test) %>%   # Makes the data somewhat long 
    separate(value, c("MEAN", "SD")) %>% # Splits "value" column. We're wide again 
    gather(MSD, value, -test, -GM) %>% # Makes the data long again 
    unite(var, GM, MSD) %>%    # Combines GM and MSD columns 
    spread(var, value)     # Goes from wide to long 

這有點melt相當於在產生的「值」列上使用colsplit,再次使用數據melt,並使用dcast來獲得寬格式。

+0

cSplit完美運作。謝謝。 – rnso

2

這裏有一個qdap方法:

library(qdap) 
for(i in seq(2, 13, by = 2)){ 
    olddf <- colsplit2df(olddf, i, 
     paste0(names(olddf)[i], "_", c("mean", "sd")), sep = "±") 
} 

olddf[,-1] <- lapply(olddf[,-1], as.numeric) 
olddf 

我在阿南達的splitstackshape包看了第一,因爲我覺得那裏是一個簡單的方法來做到這一點,但我不能想出一個辦法。

不確定是否需要將列轉換爲數字的最後一行,但假設您願意。

+0

'concat.split.multiple',但'cSplit' * *更快*。 – A5C1D2H2I1M1N2O1R2T1

+0

@AnandaMahto謝謝:-)我覺得有一種方法。 'cSplit'會在這個名字下找到'splitstackshape'還是重新啓動'concat.split.multiple'? –

+1

實際上,似乎'''在'concat.split.multiple'中不能作爲'sep'工作。 :-(我認爲'concat.split'.multiple'將最終棄用於'cSplit'。 – A5C1D2H2I1M1N2O1R2T1