मैं कॉलम के लिए शून्य पंक्ति-वार के असमान दो मानों के बीच 0 के मानों को प्रक्षेपित करने का प्रयास करता हूं: आर में data.table के 2018 से 2021 तक। इस प्रकार एक नमूना डेटा df1 इस तरह दिखेगा:

   ID string1 2018 2019 2020 2021 string2
1: a1      x2    3    3    0    4      si
2: a2      g3    5    5    4    0      q2
3: a3      n2   11    0    0    3      oq
4: a4      m3    3    0    9    8      mx
5: a5      2w    9    1    6    5      ix
6: a6     ps2    2    4    7    4      p2
7: a7     kg2    6    0    9    6      2q

सुविधाजनक प्रतिलिपि प्रस्तुत करने योग्यता के लिए:

df1 = data.table(
  ID = c("a1", "a2", "a3", "a4", "a5", "a6", "a7"),
  "string1" = c("x2", "g3", "n2", "m3", "2w", "ps2", "kg2"),
  "2018" = c(3,5,11,3,9,2,6),
  "2019" = c(3,5,0,0,1,4,0),
  "2020" = c(0,4,0,9,6,7,9),
  "2021" = c(4,0,3,8,5,4,6),
  "string2" = c("si", "q2", "oq", "mx", "ix", "p2", "2q"))

df1 में दो संख्याओं>0 (उदाहरण के लिए; पंक्ति 1/कॉलम 2020, पंक्ति 4/कॉलम 2019 या पंक्ति 7 कॉलम 2019) के बीच शून्य वाले मामले हैं। मैं इन मामलों की पहचान करने और उन्हें पड़ोसी कॉलम (उदाहरण के लिए; पंक्ति 1/कॉलम 2020: 3 + 4 = 3.5) के साथ इंटरपोलेट करने का प्रयास करता हूं।

क्या इससे निपटने का कोई तरीका है? अब तक, मुझे केवल सभी शून्य मानों को बदलने का एक तरीका मिला है, लेकिन दो संख्याओं> 0 के बीच होने की शर्त के बिना।

मैं ऐसा आउटपुट प्राप्त करने का प्रयास करता हूं:

   ID string1 2018 2019 2020 2021 string2
1: a1      x2    3  3.0  3.5    4      si
2: a2      g3    5  5.0  4.0    0      q2
3: a3      n2   11  0.0  0.0    3      oq
4: a4      m3    3  6.0  9.0    8      mx
5: a5      2w    9  1.0  6.0    5      ix
6: a6     ps2    2  4.0  7.0    4      p2
7: a7     kg2    6  7.5  9.0    6      2q

आपका बहुत बहुत धन्यवाद!

2
fjurt 25 नवम्बर 2021, 11:28
Row3 नहीं बदलता है क्योंकि दो शून्य हैं?
 – 
zx8754
25 नवम्बर 2021, 11:33
संबंधित पोस्ट: stackoverflow.com/q/26754745/680068
 – 
zx8754
25 नवम्बर 2021, 11:40
हाँ बिल्कुल, मैं केवल प्रतिस्थापित करना चाहता हूँ, यदि शून्य मान सीधे दो मानों के बीच में है> 0
 – 
fjurt
25 नवम्बर 2021, 11:46

3 जवाब

सबसे बढ़िया उत्तर

दो सकारात्मक तत्वों के बीच शून्य को प्रक्षेपित करने का कार्य:

f <- function(vec){
  
  prev_val <- shift(vec, 1, fill = 0)
  next_val <- shift(vec, -1, fill = 0)
  
  fifelse(prev_val > 0 & next_val > 0 & vec == 0, (prev_val + next_val) / 2, vec)
}

वर्ष कॉलम के लिए सभी पंक्तियों में फ़ंक्शन लागू करना:

year_cols <- names(df1)[grep("^[0-9]+$", names(df1))]
df1[, (year_cols) := transpose(lapply(transpose(.SD), f)), .SDcols = year_cols]

transpose का उपयोग किया जाता है क्योंकि आप पंक्तियों में परिवर्तन करना चाहते हैं। दूसरा उपयोग इसे कॉलम प्रारूप में वापस करना है।

4
det 25 नवम्बर 2021, 12:03
मैंने शुरुआत में ऐसा किया था लेकिन ओपी सकारात्मक चाहता था
 – 
det
25 नवम्बर 2021, 12:04
बढ़िया, यह पूरी तरह से काम करता है, आपकी मदद के लिए बहुत बहुत धन्यवाद!
 – 
fjurt
25 नवम्बर 2021, 12:05

हो सकता है कि यह एक ओवरकिल हो, लेकिन यहां दो बार रीशेपिंग का उपयोग करके एक समाधान दिया गया है:

melt(df1, measure.vars = patterns("^[0-9]+$")
     )[,value := fifelse(value == 0 &
                           shift(value, type = "lag", fill = 0) > 0 &
                           shift(value, type = "lead", fill = 0) > 0,
                         (shift(value, type = "lag") + shift(value, type = "lead")) / 2,
                         value), by = ID
       ][, dcast(.SD, ...~variable) ]

#    ID string1 string2 2018 2019 2020 2021
# 1: a1      x2      si    3  3.0  3.5    4
# 2: a2      g3      q2    5  5.0  4.0    0
# 3: a3      n2      oq   11  0.0  0.0    3
# 4: a4      m3      mx    3  6.0  9.0    8
# 5: a5      2w      ix    9  1.0  6.0    5
# 6: a6     ps2      p2    2  4.0  7.0    4
# 7: a7     kg2      2q    6  7.5  9.0    6
2
zx8754 25 नवम्बर 2021, 12:53
धन्यवाद, यह नमूना डेटासेट में भी पूरी तरह से काम करता है! व्यक्तिगत रूप से id.vars का चयन किए बिना कोई रास्ता होगा, क्योंकि मेरे पास कई कॉलम के साथ डेटा.टेबल है।
 – 
fjurt
25 नवम्बर 2021, 12:39
1
संपादित करें देखें, हम पैटर्न का उपयोग करके "माप" कॉलम का चयन कर सकते हैं, इसलिए बाकी कॉलम id.vars बन जाते हैं।
 – 
zx8754
25 नवम्बर 2021, 12:54

data.table फ़ंक्शंस (और मूल डेटा.फ़्रेम) का उपयोग करके, यह कोड (थोड़ा बोझिल) काम करना चाहिए:

for (i in c(2019,2020)){
  x = which(colnames(df1) == i)
  df1[,x] <- ifelse(c(df1[,.SD,.SDcols = x] == 0 & df1[,.SD,.SDcols = c(x-1)] > 0 & df1[,.SD,.SDcols = c(x+1)] > 0), 
                    rowMeans(df1[,.SD,.SDcols = c(x-1,x+1)]), unlist(df1[,.SD,.SDcols = x]))
}

> df1
   ID string1 2018 2019 2020 2021 string2
1: a1      x2    3  3.0  3.5    4      si
2: a2      g3    5  5.0  4.0    0      q2
3: a3      n2   11  0.0  0.0    3      oq
4: a4      m3    3  6.0  9.0    8      mx
5: a5      2w    9  1.0  6.0    5      ix
6: a6     ps2    2  4.0  7.0    4      p2
7: a7     kg2    6  7.5  9.0    6      2q

और यहाँ एक आधार R समाधान है (डेटा उत्पन्न करने के लिए data.table के बजाय data.frame का उपयोग करके):

for (i in c("X2019","X2020")){
  x = which(colnames(df1) == i)
  df1[,x] <- ifelse(df1[,x] == 0 & df1[,x-1] > 0 & df1[,x+1] > 0, rowMeans(df1[,c(x-1,x+1)]), df1[,x])
}
1
Maël 25 नवम्बर 2021, 13:03
आपके आधार आर समाधान के लिए बहुत बहुत धन्यवाद। अगर मैं इसे चलाता हूं, तो मुझे मिलता है: जे (अंदर दूसरा तर्क [...]) एक एकल प्रतीक है लेकिन कॉलम नाम 'x' नहीं मिला है। शायद आप डीटी [, ..x] का इरादा रखते हैं। data.frame में यह अंतर जानबूझकर है और अक्सर पूछे जाने वाले प्रश्न 1.1 में समझाया गया है।
 – 
fjurt
25 नवम्बर 2021, 12:24
ऐसा इसलिए है क्योंकि मैं आपके डेटासेट को data.frame से लोड करता हूं न कि data.table के साथ। संख्यात्मक नाम स्तंभों को data.frame के साथ नियंत्रित नहीं किया जाता है, इसलिए उन्हें X{numerical value} में बदल दिया जाता है। उम्मीद है ये मदद करेगा!
 – 
Maël
25 नवम्बर 2021, 12:29
सत्यापन के बाद, यह वास्तव में इस तथ्य के कारण है कि जब आप data.table पैकेज लोड करते हैं, तो डेटा.टेबल फ़ंक्शन का उपयोग आधार R फ़ंक्शंस जैसे ` [ ` पर किया जाता है।
 – 
Maël
25 नवम्बर 2021, 12:34
क्या data.table को data.frame में कनवर्ट किए बिना लूप के लिए बदलने का कोई आसान तरीका है?
 – 
fjurt
25 नवम्बर 2021, 12:34
1
मैंने अपना जवाब संपादित किया, मुझे बताएं कि क्या यह काम करता है! मुझे पूरा यकीन है कि data.table में कोई और उन्नत व्यक्ति इसे छोटा और बेहतर बना सकता है, लेकिन मैंने आधार R समाधान से अनुकूलन करने की कोशिश की।
 – 
Maël
25 नवम्बर 2021, 13:00